/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.anjocaido.groupmanager.permissions; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.data.Group; import org.anjocaido.groupmanager.dataholder.WorldDataHolder; import org.anjocaido.groupmanager.data.User; import org.anjocaido.groupmanager.utils.PermissionCheckResult; import org.anjocaido.groupmanager.utils.PermissionCheckResult.Type; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; /** * Everything here maintains the model created by Nijikokun * * But implemented to use GroupManager system. Which provides instant changes, * without file access. * * It holds permissions only for one single world. * * @author gabrielcouto */ public class AnjoPermissionsHandler extends PermissionsReaderInterface { WorldDataHolder ph = null; /** * It needs a WorldDataHolder to work with. * * @param holder */ public AnjoPermissionsHandler(WorldDataHolder holder) { ph = holder; } /** * A short name method, for permission method. * * @param player * @param permission * @return true if the player has the permission */ @Override public boolean has(Player player, String permission) { return permission(player, permission); } /** * Checks if a player can use that permission node. * * @param player * @param permission * @return true if the player has the permission */ @Override public boolean permission(Player player, String permission) { return checkUserPermission(ph.getUser(player.getName()).updatePlayer(player), permission); } /** * Checks if a player can use that permission node. * * @param playerName * @param permission * @return true if the player has the permission */ public boolean permission(String playerName, String permission) { return checkUserPermission(ph.getUser(playerName), permission); } /** * Returns the name of the group of that player name. * * @param userName * @return String of players group name. */ @Override public String getGroup(String userName) { return ph.getUser(userName).getGroup().getName(); } /** * Returns All permissions (including inheritance and sub groups) for the * player. * * @param userName * @return List of all players permissions. */ @Override public List getAllPlayersPermissions(String userName) { List playerPermArray = new ArrayList(); for (String perm : ph.getUser(userName).getPermissionList()) { if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { playerPermArray.add(perm); Map children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray); if (children != null) { for (String child : children.keySet()) { if (children.get(child)) if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) { playerPermArray.add(child); } } } } } for (String group : getGroups(userName)) { if (group.startsWith("g:") && GroupManager.getGlobalGroups().hasGroup(group)) { for (String perm : GroupManager.getGlobalGroups().getGroupsPermissions(group)) { if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { playerPermArray.add(perm); Map children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray); if (children != null) { for (String child : children.keySet()) { if (children.get(child)) if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) playerPermArray.add(child); } } } } } else { for (String perm : ph.getGroup(group).getPermissionList()) { if ((!playerPermArray.contains(perm)) && (!playerPermArray.contains("-" + perm))) { playerPermArray.add(perm); Map children = GroupManager.BukkitPermissions.getAllChildren(perm, playerPermArray); if (children != null) { for (String child : children.keySet()) { if (children.get(child)) if ((!playerPermArray.contains(child)) && (!playerPermArray.contains("-" + child))) { playerPermArray.add(child); } } } } } } } // Collections.sort(playerPermArray, // StringPermissionComparator.getInstance()); return playerPermArray; } /** * Verify if player is in such group. It will check it's groups inheritance. * * So if you have a group Admin > Moderator * * And verify the player 'MyAdmin', which is Admin, it will return true for * both Admin or Moderator groups. * * If you have a player 'MyModerator', which is Moderator, it will give * false if you pass Admin in group parameter. * * @param name * @param group * @return true if in group (with inheritance) */ @Override public boolean inGroup(String name, String group) { if (hasGroupInInheritance(ph.getUser(name).getGroup(), group)) { return true; } for (Group subGroup : ph.getUser(name).subGroupListCopy()) { if (hasGroupInInheritance(subGroup, group)) { return true; } } return false; } /** * Gets the appropriate prefix for the user. This method is a utility method * for chat plugins to get the user's prefix without having to look at every * one of the user's ancestors. Returns an empty string if user has no * parent groups. * * @param user * Player's name * @return Player's prefix */ @Override public String getUserPrefix(String user) { String prefix = ph.getUser(user).getVariables().getVarString("prefix"); if (prefix.length() != 0) { return prefix; } return getGroupPrefix(getGroup(user)); } /** * Gets the appropriate prefix for the user. This method is a utility method * for chat plugins to get the user's prefix without having to look at every * one of the user's ancestors. Returns an empty string if user has no * parent groups. * * @param user * Player's name * @return Player's prefix */ @Override public String getUserSuffix(String user) { String suffix = ph.getUser(user).getVariables().getVarString("suffix"); if (suffix.length() != 0) { return suffix; } return getGroupSuffix(getGroup(user)); } /** * Gets name of the primary group of the user. Returns the name of the * default group if user has no parent groups, or "Default" if there is no * default group for that world. * * @param user * Player's name * @return Name of player's primary group */ public String getPrimaryGroup(String user) { return getGroup(user); } /** * Check if user can build. Checks inheritance and subgroups. * * @param userName * Player's name * @return true if the user can build */ public boolean canUserBuild(String userName) { return getPermissionBoolean(userName, "build"); } /** * Returns the String prefix for the given group * * @param groupName * @return empty string if found none. */ @Override public String getGroupPrefix(String groupName) { Group g = ph.getGroup(groupName); if (g == null) { return ""; } return g.getVariables().getVarString("prefix"); } /** * Return the suffix for the given group name * * @param groupName * @return empty string if not found. */ @Override public String getGroupSuffix(String groupName) { Group g = ph.getGroup(groupName); if (g == null) { return ""; } return g.getVariables().getVarString("suffix"); } /** * Checks the specified group for the Info Build node. Does NOT check * inheritance * * @param groupName * @return true if can build */ @Override public boolean canGroupBuild(String groupName) { Group g = ph.getGroup(groupName); if (g == null) { return false; } return g.getVariables().getVarBoolean("build"); } /** * It returns a string variable value, set in the INFO node of the group. It * will harvest inheritance for value. * * @param groupName * @param variable * @return null if no group with that variable is found. */ @Override public String getGroupPermissionString(String groupName, String variable) { Group start = ph.getGroup(groupName); if (start == null) { return null; } Group result = nextGroupWithVariable(start, variable); if (result == null) { return null; } return result.getVariables().getVarString(variable); } /** * It returns a Integer variable value It will harvest inheritance for * value. * * @param groupName * @param variable * @return -1 if none found or not parseable. */ @Override public int getGroupPermissionInteger(String groupName, String variable) { Group start = ph.getGroup(groupName); if (start == null) { return -1; } Group result = nextGroupWithVariable(start, variable); if (result == null) { return -1; } return result.getVariables().getVarInteger(variable); } /** * Returns a boolean for given variable in INFO node. It will harvest * inheritance for value. * * @param group * @param variable * @return false if not found/not parseable. */ @Override public boolean getGroupPermissionBoolean(String group, String variable) { Group start = ph.getGroup(group); if (start == null) { return false; } Group result = nextGroupWithVariable(start, variable); if (result == null) { return false; } return result.getVariables().getVarBoolean(variable); } /** * Returns a double value for the given variable name in INFO node. It will * harvest inheritance for value. * * @param group * @param variable * @return -1 if not found / not parseable. */ @Override public double getGroupPermissionDouble(String group, String variable) { Group start = ph.getGroup(group); if (start == null) { return -1; } Group result = nextGroupWithVariable(start, variable); if (result == null) { return -1; } return result.getVariables().getVarDouble(variable); } /** * Returns the variable value of the user, in INFO node. * * @param user * @param variable * @return empty string if not found */ @Override public String getUserPermissionString(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return ""; } return auser.getVariables().getVarString(variable); } /** * Returns the variable value of the user, in INFO node. * * @param user * @param variable * @return -1 if not found */ @Override public int getUserPermissionInteger(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return -1; } return auser.getVariables().getVarInteger(variable); } /** * Returns the variable value of the user, in INFO node. * * @param user * @param variable * @return boolean value */ @Override public boolean getUserPermissionBoolean(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return false; } return auser.getVariables().getVarBoolean(variable); } /** * Returns the variable value of the user, in INFO node. * * @param user * @param variable * @return -1 if not found */ @Override public double getUserPermissionDouble(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return -1; } return auser.getVariables().getVarDouble(variable); } /** * Returns the variable value of the user, in INFO node. If not found, it * will search for his Group variables. It will harvest the inheritance and * subgroups. * * @param user * @param variable * @return empty string if not found */ @Override public String getPermissionString(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return ""; } if (auser.getVariables().hasVar(variable)) { return auser.getVariables().getVarString(variable); } Group start = auser.getGroup(); if (start == null) { return ""; } Group result = nextGroupWithVariable(start, variable); if (result == null) { // Check sub groups if (!auser.isSubGroupsEmpty()) for (Group subGroup : auser.subGroupListCopy()) { result = nextGroupWithVariable(subGroup, variable); // Found value? if (result != null) continue; } if (result == null) return ""; } return result.getVariables().getVarString(variable); // return getUserPermissionString(user, variable); } /** * Returns the variable value of the user, in INFO node. If not found, it * will search for his Group variables. It will harvest the inheritance and * subgroups. * * @param user * @param variable * @return -1 if not found */ @Override public int getPermissionInteger(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return -1; } if (auser.getVariables().hasVar(variable)) { return auser.getVariables().getVarInteger(variable); } Group start = auser.getGroup(); if (start == null) { return -1; } Group result = nextGroupWithVariable(start, variable); if (result == null) { // Check sub groups if (!auser.isSubGroupsEmpty()) for (Group subGroup : auser.subGroupListCopy()) { result = nextGroupWithVariable(subGroup, variable); // Found value? if (result != null) continue; } if (result == null) return -1; } return result.getVariables().getVarInteger(variable); // return getUserPermissionInteger(string, string1); } /** * Returns the variable value of the user, in INFO node. If not found, it * will search for his Group variables. It will harvest the inheritance and * subgroups. * * @param user * @param variable * @return false if not found or not parseable to true. */ @Override public boolean getPermissionBoolean(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return false; } if (auser.getVariables().hasVar(variable)) { return auser.getVariables().getVarBoolean(variable); } Group start = auser.getGroup(); if (start == null) { return false; } Group result = nextGroupWithVariable(start, variable); if (result == null) { // Check sub groups if (!auser.isSubGroupsEmpty()) for (Group subGroup : auser.subGroupListCopy()) { result = nextGroupWithVariable(subGroup, variable); // Found value? if (result != null) continue; } if (result == null) return false; } return result.getVariables().getVarBoolean(variable); // return getUserPermissionBoolean(user, string1); } /** * Returns the variable value of the user, in INFO node. If not found, it * will search for his Group variables. It will harvest the inheritance and * subgroups. * * @param user * @param variable * @return -1 if not found. */ @Override public double getPermissionDouble(String user, String variable) { User auser = ph.getUser(user); if (auser == null) { return -1.0D; } if (auser.getVariables().hasVar(variable)) { return auser.getVariables().getVarDouble(variable); } Group start = auser.getGroup(); if (start == null) { return -1.0D; } Group result = nextGroupWithVariable(start, variable); if (result == null) { // Check sub groups if (!auser.isSubGroupsEmpty()) for (Group subGroup : auser.subGroupListCopy()) { result = nextGroupWithVariable(subGroup, variable); // Found value? if (result != null) continue; } if (result == null) return -1.0D; } return result.getVariables().getVarDouble(variable); // return getUserPermissionDouble(string, string1); } /** * Does not include User's group permission * * @param user * @param permission * @return PermissionCheckResult */ public PermissionCheckResult checkUserOnlyPermission(User user, String permission) { user.sortPermissions(); PermissionCheckResult result = new PermissionCheckResult(); result.askedPermission = permission; result.owner = user; for (String access : user.getPermissionList()) { result.resultType = comparePermissionString(access, permission); if (result.resultType != PermissionCheckResult.Type.NOTFOUND) { return result; } } result.resultType = PermissionCheckResult.Type.NOTFOUND; return result; } /** * Returns the node responsible for that permission. Does not include User's * group permission. * * @param group * @param permission * @return the node if permission is found. if not found, return null */ public PermissionCheckResult checkGroupOnlyPermission(Group group, String permission) { group.sortPermissions(); PermissionCheckResult result = new PermissionCheckResult(); result.owner = group; result.askedPermission = permission; for (String access : group.getPermissionList()) { result.resultType = comparePermissionString(access, permission); if (result.resultType != PermissionCheckResult.Type.NOTFOUND) { return result; } } result.resultType = PermissionCheckResult.Type.NOTFOUND; return result; } /** * Check permissions, including it's group and inheritance. * * @param user * @param permission * @return true if permission was found. false if not, or was negated. */ public boolean checkUserPermission(User user, String permission) { PermissionCheckResult result = checkFullGMPermission(user, permission, true); if (result.resultType == PermissionCheckResult.Type.EXCEPTION || result.resultType == PermissionCheckResult.Type.FOUND) { return true; } return false; } /** * Do what checkUserPermission did before. But now returning a * PermissionCheckResult. * * @param user * @param targetPermission * @return PermissionCheckResult */ public PermissionCheckResult checkFullUserPermission(User user, String targetPermission) { return checkFullGMPermission(user, targetPermission, true); } /** * Check user and groups with inheritance and Bukkit if bukkit = true return * a PermissionCheckResult. * * @param user * @param targetPermission * @param checkBukkit * @return PermissionCheckResult */ public PermissionCheckResult checkFullGMPermission(User user, String targetPermission, Boolean checkBukkit) { PermissionCheckResult result = new PermissionCheckResult(); result.accessLevel = targetPermission; result.resultType = PermissionCheckResult.Type.NOTFOUND; if (user == null || targetPermission == null || targetPermission.isEmpty()) { return result; } if (checkBukkit) { // Check Bukkit perms to support plugins which add perms via code // (Heroes). final Player player = user.getBukkitPlayer(); final Permission bukkitPerm = Bukkit.getPluginManager().getPermission(targetPermission); if (player != null && bukkitPerm != null) { result.resultType = player.hasPermission(bukkitPerm) ? PermissionCheckResult.Type.FOUND : PermissionCheckResult.Type.NEGATION; result.owner = user; return result; } } PermissionCheckResult resultUser = checkUserOnlyPermission(user, targetPermission); if (resultUser.resultType != PermissionCheckResult.Type.NOTFOUND) { resultUser.accessLevel = targetPermission; return resultUser; } // IT ONLY CHECKS GROUPS PERMISSIONS IF RESULT FOR USER IS NOT FOUND PermissionCheckResult resultGroup = checkGroupPermissionWithInheritance(user.getGroup(), targetPermission); if (resultGroup.resultType != PermissionCheckResult.Type.NOTFOUND) { result.accessLevel = targetPermission; return resultGroup; } // SUBGROUPS CHECK for (Group subGroup : user.subGroupListCopy()) { PermissionCheckResult resultSubGroup = checkGroupPermissionWithInheritance(subGroup, targetPermission); if (resultSubGroup.resultType != PermissionCheckResult.Type.NOTFOUND) { resultSubGroup.accessLevel = targetPermission; return resultSubGroup; } } // THEN IT RETURNS A NOT FOUND return result; } /** * Verifies if a given group has a variable. Including it's inheritance. * * it redirects to the other method now. This one was deprecated, and will * be gone in a future release. * * @param start * @param variable * @param alreadyChecked * @return returns the closest inherited group with the variable. * @deprecated use now nextGroupWithVariable(Group start, String * targetVariable) */ @Deprecated public Group nextGroupWithVariable(Group start, String variable, List alreadyChecked) { return nextGroupWithVariable(start, variable); } /** * Returns the next group, including inheritance, which contains that * variable name. * * It does Breadth-first search * * @param start * the starting group to look for * @param targetVariable * the variable name * @return The group if found. Null if not. */ public Group nextGroupWithVariable(Group start, String targetVariable) { if (start == null || targetVariable == null) { return null; } LinkedList stack = new LinkedList(); ArrayList alreadyVisited = new ArrayList(); stack.push(start); alreadyVisited.add(start); while (!stack.isEmpty()) { Group now = stack.pop(); if (now.getVariables().hasVar(targetVariable)) { return now; } for (String sonName : now.getInherits()) { Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son)) { stack.push(son); alreadyVisited.add(son); } } } return null; } /** * Check if given group inherits another group. * * redirected to the other method. this is deprecated now. and will be gone * in the future releases. * * @param start * The group to start the search. * @param askedGroup * Name of the group you're looking for * @param alreadyChecked * groups to ignore(pass null on it, please) * @return true if it inherits the group. * @deprecated prefer using hasGroupInInheritance(Group start, String * askedGroup) */ @Deprecated public boolean searchGroupInInheritance(Group start, String askedGroup, List alreadyChecked) { return hasGroupInInheritance(start, askedGroup); } /** * Check if given group inherits another group. * * It does Breadth-first search * * @param start * The group to start the search. * @param askedGroup * Name of the group you're looking for * @return true if it inherits the group. */ public boolean hasGroupInInheritance(Group start, String askedGroup) { if (start == null || askedGroup == null) { return false; } LinkedList stack = new LinkedList(); ArrayList alreadyVisited = new ArrayList(); stack.push(start); alreadyVisited.add(start); while (!stack.isEmpty()) { Group now = stack.pop(); if (now.getName().equalsIgnoreCase(askedGroup)) { return true; } for (String sonName : now.getInherits()) { Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son)) { stack.push(son); alreadyVisited.add(son); } } } return false; } /** * Check if the group has given permission. Including it's inheritance * * @param start * @param permission * @param alreadyChecked * @return true if PermissionCheckResult is EXCEPTION or FOUND * @deprecated use the other checkGroupPermissionWithInheritance for * everything */ @Deprecated public boolean checkGroupPermissionWithInheritance(Group start, String permission, List alreadyChecked) { PermissionCheckResult result = checkGroupPermissionWithInheritance(start, permission); if (result.resultType.equals(Type.EXCEPTION) || result.resultType.equals(Type.FOUND)) { return true; } return false; } /** * Returns the result of permission check. Including inheritance. If found * anything, the PermissionCheckResult that retuns will include the Group * name, and the result type. Result types will be EXCEPTION, NEGATION, * FOUND. * * If returned type NOTFOUND, the owner will be null, and ownerType too. * * It does Breadth-first search * * @param start * @param targetPermission * @return PermissionCheckResult */ public PermissionCheckResult checkGroupPermissionWithInheritance(Group start, String targetPermission) { if (start == null || targetPermission == null) { return null; } LinkedList stack = new LinkedList(); List alreadyVisited = new ArrayList(); stack.push(start); alreadyVisited.add(start); while (!stack.isEmpty()) { Group now = stack.pop(); PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targetPermission); if (!resultNow.resultType.equals(PermissionCheckResult.Type.NOTFOUND)) { return resultNow; } for (String sonName : now.getInherits()) { Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son)) { stack.push(son); alreadyVisited.add(son); } } } PermissionCheckResult result = new PermissionCheckResult(); result.askedPermission = targetPermission; result.resultType = PermissionCheckResult.Type.NOTFOUND; return result; } /** * It uses checkGroupPermissionWithInheritance and cast the owner to Group * type if result type was EXCEPTION or FOUND. * * @param start * @param permission * @param alreadyChecked * @return the group that passed on test. null if no group passed. * @deprecated use checkGroupPermissionWithInheritance for everything now. */ @Deprecated public Group nextGroupWithPermission(Group start, String permission, List alreadyChecked) { PermissionCheckResult result = checkGroupPermissionWithInheritance(start, permission); if (result.resultType.equals(Type.EXCEPTION) || result.resultType.equals(Type.FOUND)) { return (Group) checkGroupPermissionWithInheritance(start, permission).owner; } return null; } /** * Return whole list of names of groups in a inheritance chain. Including a * starting group. * * it now redirects to the other method. but get away from this one, it will * disappear in a future release. * * @param start * @param alreadyChecked * @return the group that passed on test. null if no group passed. * @deprecated use the other method with same name, instead */ @Deprecated public ArrayList listAllGroupsInherited(Group start, ArrayList alreadyChecked) { return listAllGroupsInherited(start); } /** * Return whole list of names of groups in a inheritance chain. Including a * starting group. * * It does Breadth-first search. So closer groups will appear first in list. * * @param start * @return the group that passed on test. null if no group passed. */ public ArrayList listAllGroupsInherited(Group start) { if (start == null) { return null; } LinkedList stack = new LinkedList(); ArrayList alreadyVisited = new ArrayList(); stack.push(start); alreadyVisited.add(start.getName()); while (!stack.isEmpty()) { Group now = stack.pop(); for (String sonName : now.getInherits()) { Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son.getName())) { stack.push(son); alreadyVisited.add(son.getName()); } } } return alreadyVisited; } /** * Compare a user permission like 'myplugin.*' against a full plugin * permission name, like 'myplugin.dosomething'. As the example above, will * return true. * * Please sort permissions before sending them here. So negative tokens get * priority. * * You must test if it start with negative outside this method. It will only * tell if the nodes are matching or not. * * Every '-' or '+' in the beginning is ignored. It will match only node * names. * * @param userAccessLevel * @param fullPermissionName * @return PermissionCheckResult.Type */ public PermissionCheckResult.Type comparePermissionString(String userAccessLevel, String fullPermissionName) { int userAccessLevelLength; if (userAccessLevel == null || fullPermissionName == null || fullPermissionName.length() == 0 || (userAccessLevelLength = userAccessLevel.length()) == 0) { return PermissionCheckResult.Type.NOTFOUND; } PermissionCheckResult.Type result = PermissionCheckResult.Type.FOUND; int userAccessLevelOffset = 0; if (userAccessLevel.charAt(0) == '+') { userAccessLevelOffset = 1; result = PermissionCheckResult.Type.EXCEPTION; } else if (userAccessLevel.charAt(0) == '-') { userAccessLevelOffset = 1; result = PermissionCheckResult.Type.NEGATION; } if ("*".regionMatches(0, userAccessLevel, userAccessLevelOffset, userAccessLevelLength - userAccessLevelOffset)) { return result; } int fullPermissionNameOffset; if (fullPermissionName.charAt(0) == '+' || fullPermissionName.charAt(0) == '-') { fullPermissionNameOffset = 1; } else { fullPermissionNameOffset = 0; } if (userAccessLevel.charAt(userAccessLevel.length() - 1) == '*') { return userAccessLevel.regionMatches(true, userAccessLevelOffset, fullPermissionName, fullPermissionNameOffset, userAccessLevelLength - userAccessLevelOffset - 1) ? result : PermissionCheckResult.Type.NOTFOUND; } else { return userAccessLevel.regionMatches(true, userAccessLevelOffset, fullPermissionName, fullPermissionNameOffset, Math.max(userAccessLevelLength - userAccessLevelOffset, fullPermissionName.length() - fullPermissionNameOffset)) ? result : PermissionCheckResult.Type.NOTFOUND; } } /** * Returns a list of all groups. * * Including subgroups. * * @param userName * @return String[] of all group names. */ @Override public String[] getGroups(String userName) { ArrayList allGroups = listAllGroupsInherited(ph.getUser(userName).getGroup()); for (Group subg : ph.getUser(userName).subGroupListCopy()) { allGroups.addAll(listAllGroupsInherited(subg)); } String[] arr = new String[allGroups.size()]; return allGroups.toArray(arr); } /** * A Breadth-first search thru inheritance model. * * Just a model to copy and paste. This will guarantee the closer groups * will be checked first. * * @param start * @param targerPermission * @return */ @SuppressWarnings("unused") private Group breadthFirstSearch(Group start, String targerPermission) { if (start == null || targerPermission == null) { return null; } LinkedList stack = new LinkedList(); ArrayList alreadyVisited = new ArrayList(); stack.push(start); alreadyVisited.add(start); while (!stack.isEmpty()) { Group now = stack.pop(); PermissionCheckResult resultNow = checkGroupOnlyPermission(now, targerPermission); if (resultNow.resultType.equals(PermissionCheckResult.Type.EXCEPTION) || resultNow.resultType.equals(PermissionCheckResult.Type.FOUND)) { return now; } if (resultNow.resultType.equals(PermissionCheckResult.Type.NEGATION)) { return null; } for (String sonName : now.getInherits()) { Group son = ph.getGroup(sonName); if (son != null && !alreadyVisited.contains(son)) { stack.push(son); alreadyVisited.add(son); } } } return null; } @Override public Group getDefaultGroup() { return ph.getDefaultGroup(); } @Override public String getInfoString(String entryName, String path, boolean isGroup) { if (isGroup) { Group data = ph.getGroup(entryName); if (data == null) { return null; } return data.getVariables().getVarString(path); } else { User data = ph.getUser(entryName); if (data == null) { return null; } return data.getVariables().getVarString(path); } } @Override public int getInfoInteger(String entryName, String path, boolean isGroup) { if (isGroup) { Group data = ph.getGroup(entryName); if (data == null) { return -1; } return data.getVariables().getVarInteger(path); } else { User data = ph.getUser(entryName); if (data == null) { return -1; } return data.getVariables().getVarInteger(path); } } @Override public double getInfoDouble(String entryName, String path, boolean isGroup) { if (isGroup) { Group data = ph.getGroup(entryName); if (data == null) { return -1; } return data.getVariables().getVarDouble(path); } else { User data = ph.getUser(entryName); if (data == null) { return -1; } return data.getVariables().getVarDouble(path); } } @Override public boolean getInfoBoolean(String entryName, String path, boolean isGroup) { if (isGroup) { Group data = ph.getGroup(entryName); if (data == null) { return false; } return data.getVariables().getVarBoolean(path); } else { User data = ph.getUser(entryName); if (data == null) { return false; } return data.getVariables().getVarBoolean(path); } } @Override public void addUserInfo(String name, String path, Object data) { ph.getUser(name).getVariables().addVar(path, data); } @Override public void removeUserInfo(String name, String path) { ph.getUser(name).getVariables().removeVar(path); } @Override public void addGroupInfo(String name, String path, Object data) { ph.getGroup(name).getVariables().addVar(path, data); } @Override public void removeGroupInfo(String name, String path) { ph.getGroup(name).getVariables().removeVar(path); } }