package pex.permissions.backends.file; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.bukkit.configuration.ConfigurationSection; import pex.permissions.PermissionGroup; import pex.permissions.PermissionsGroupData; import pex.permissions.PermissionsUserData; import pex.permissions.backends.FileBackend; public class FileData implements PermissionsUserData, PermissionsGroupData { protected transient FileConfig config; protected String nodePath; protected ConfigurationSection node; protected boolean virtual = true; public FileData(String basePath, String name, FileConfig config) { this.config = config; node = findNode(name, basePath); } private ConfigurationSection findNode(String entityName, String basePath) { nodePath = FileBackend.buildPath(basePath, entityName); ConfigurationSection entityNode = config.getConfigurationSection(nodePath); if (entityNode != null) { virtual = false; return entityNode; } ConfigurationSection users = config.getConfigurationSection(basePath); if (users != null) { for (Map.Entry<String, Object> entry : users.getValues(false).entrySet()) { if (entry.getKey().equalsIgnoreCase(entityName) && entry.getValue() instanceof ConfigurationSection) { nodePath = FileBackend.buildPath(basePath, entityName); return (ConfigurationSection) entry.getValue(); } } } // Silly workaround for empty nodes ConfigurationSection section = config.createSection(nodePath); config.set(nodePath, null); return section; } /** * Permissions */ @Override public List<String> getPermissions(String worldName) { List<String> result = node.getStringList(formatPath(worldName, "permissions")); return result == null ? new LinkedList<String>() : result; } @Override public void setPermissions(List<String> permissions, String worldName) { node.set(formatPath(worldName, "permissions"), permissions.isEmpty() ? null : permissions); } @Override public Map<String, List<String>> getPermissionsMap() { Map<String, List<String>> allPermissions = new HashMap<String, List<String>>(); // Common permissions List<String> commonPermissions = node.getStringList("permissions"); if (commonPermissions != null) { allPermissions.put(null, commonPermissions); } // World-specific permissions ConfigurationSection worldsSection = node.getConfigurationSection("worlds"); if (worldsSection != null) { for (String world : worldsSection.getKeys(false)) { List<String> worldPermissions = node.getStringList(FileBackend.buildPath("worlds", world, "permissions")); if (commonPermissions != null) { allPermissions.put(world, worldPermissions); } } } return allPermissions; } @Override public Set<String> getWorlds() { ConfigurationSection worldsSection = node.getConfigurationSection("worlds"); if (worldsSection == null) { return new HashSet<String>(); } return worldsSection.getKeys(false); } @Override public String getPrefix(String worldName) { return node.getString(formatPath(worldName, "prefix")); } @Override public void setPrefix(String prefix, String worldName) { node.set(formatPath(worldName, "prefix"), prefix); } @Override public String getSuffix(String worldName) { return node.getString(formatPath(worldName, "suffix")); } @Override public void setSuffix(String suffix, String worldName) { node.set(formatPath(worldName, "suffix"), suffix); } @Override public String getOption(String option, String worldName) { return node.getString(formatPath(worldName, "options", option)); } @Override public void setOption(String option, String worldName, String value) { node.set(formatPath(worldName, "options", option), value); } @Override public Map<String, String> getOptions(String worldName) { ConfigurationSection optionsSection = node.getConfigurationSection(formatPath(worldName, "options")); if (optionsSection == null) { return new HashMap<String, String>(0); } return collectOptions(optionsSection); } @Override public Map<String, Map<String, String>> getOptionsMap() { Map<String, Map<String, String>> allOptions = new HashMap<String, Map<String, String>>(); allOptions.put(null, getOptions(null)); for (String worldName : getWorlds()) { allOptions.put(worldName, getOptions(worldName)); } return allOptions; } @Override public boolean isVirtual() { return config.isConfigurationSection(nodePath); } @Override public void save() { config.save(); } @Override public void remove() { config.set(nodePath, null); save(); } @SuppressWarnings("unchecked") @Override public List<String> getGroups(String worldName) { Object groups = node.get(FileEntity.formatPath(worldName, "group")); if (groups instanceof String) { // old style String[] groupsArray; String groupsString = (String) groups; if (groupsString.contains(",")) { groupsArray = ((String) groups).split(","); } else { groupsArray = new String[] { groupsString }; } return Arrays.asList(groupsArray); } else if (groups instanceof List) { return (List<String>) groups; } else { return new ArrayList<String>(0); } } @Override public void setGroups(List<PermissionGroup> groups, String worldName) { node.set(FileEntity.formatPath(worldName, "group"), groups); } @Override public List<String> getParents(String worldName) { List<String> parents = node.getStringList(FileEntity.formatPath(worldName, "inheritance")); if (parents.isEmpty()) { return new ArrayList<String>(0); } return parents; } @Override public void setParents(String worldName, List<String> parents) { node.set(FileEntity.formatPath(worldName, "inheritance"), parents); } private Map<String, String> collectOptions(ConfigurationSection section) { Map<String, String> options = new LinkedHashMap<String, String>(); for (String key : section.getKeys(true)) { if (section.isConfigurationSection(key)) { continue; } options.put(key.replace(section.getRoot().options().pathSeparator(), '.'), section.getString(key)); } return options; } protected static String formatPath(String worldName, String node, String value) { String path = FileBackend.buildPath(node, value); if (worldName != null && !worldName.isEmpty()) { path = FileBackend.buildPath("worlds", worldName, path); } return path; } protected static String formatPath(String worldName, String node) { String path = node; if (worldName != null && !worldName.isEmpty()) { path = FileBackend.buildPath("worlds", worldName, path); } return path; } }