Permalink
Browse files

Permission registration in plugin.yml can now be easier, see https://…

…gist.github.com/32dca3e937c1c42a4ed2 - also added "default-permission" option.
  • Loading branch information...
Dinnerbone committed Sep 20, 2011
1 parent ee31c5d commit 326f2aca9b98d1d096842d3410000ed9d84611f5
@@ -1,19 +1,25 @@
package org.bukkit.permissions;
+import java.util.ArrayList;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.logging.Level;
import org.bukkit.Bukkit;
+import org.bukkit.plugin.PluginManager;
/**
* Represents a unique permission that may be attached to a {@link Permissible}
*/
public class Permission {
+ public static final PermissionDefault DEFAULT_PERMISSION = PermissionDefault.FALSE;
+
private final String name;
private final Map<String, Boolean> children = new LinkedHashMap<String, Boolean>();
- private PermissionDefault defaultValue = PermissionDefault.FALSE;
+ private PermissionDefault defaultValue = DEFAULT_PERMISSION;
private String description;
public Permission(String name) {
@@ -152,6 +158,68 @@ public void recalculatePermissibles() {
}
}
+ /**
+ * Adds this permission to the specified parent permission.
+ *
+ * If the parent permission does not exist, it will be created and registered.
+ *
+ * @param name Name of the parent permission
+ * @param value The value to set this permission to
+ * @return Parent permission it created or loaded
+ */
+ public Permission addParent(String name, boolean value) {
+ PluginManager pm = Bukkit.getServer().getPluginManager();
+ String lname = name.toLowerCase();
+
+ Permission perm = pm.getPermission(lname);
+
+ if (perm == null) {
+ perm = new Permission(lname);
+ pm.addPermission(perm);
+ }
+
+ addParent(perm, value);
+
+ return perm;
+ }
+
+ /**
+ * Adds this permission to the specified parent permission.
+ *
+ * @param perm Parent permission to register with
+ * @param value The value to set this permission to
+ */
+ public void addParent(Permission perm, boolean value) {
+ perm.getChildren().put(getName(), value);
+ perm.recalculatePermissibles();
+ }
+
+ /**
+ * Loads a list of Permissions from a map of data, usually used from retrieval from a yaml file.
+ *
+ * The data may contain a list of name:data, where the data contains the following keys:
+ * default: Boolean true or false. If not specified, false.
+ * children: Map<String, Boolean> of child permissions. If not specified, empty list.
+ * description: Short string containing a very small description of this description. If not specified, empty string.
+ *
+ * @param data Map of permissions
+ * @param def Default permission value to use if missing
+ * @return Permission object
+ */
+ public static List<Permission> loadPermissions(Map<String, Map<String, Object>> data, String error, PermissionDefault def) {
+ List<Permission> result = new ArrayList<Permission>();
+
+ for (Map.Entry<String, Map<String, Object>> entry : data.entrySet()) {
+ try {
+ result.add(Permission.loadPermission(entry.getKey(), entry.getValue(), def, result));
+ } catch (Throwable ex) {
+ Bukkit.getServer().getLogger().log(Level.SEVERE, String.format(error, entry.getKey()), ex);
+ }
+ }
+
+ return result;
+ }
+
/**
* Loads a Permission from a map of data, usually used from retrieval from a yaml file.
*
@@ -165,14 +233,31 @@ public void recalculatePermissibles() {
* @return Permission object
*/
public static Permission loadPermission(String name, Map<String, Object> data) {
+ return loadPermission(name, data, DEFAULT_PERMISSION, null);
+ }
+
+ /**
+ * Loads a Permission from a map of data, usually used from retrieval from a yaml file.
+ *
+ * The data may contain the following keys:
+ * default: Boolean true or false. If not specified, false.
+ * children: Map<String, Boolean> of child permissions. If not specified, empty list.
+ * description: Short string containing a very small description of this description. If not specified, empty string.
+ *
+ * @param name Name of the permission
+ * @param data Map of keys
+ * @param def Default permission value to use if not set
+ * @param output A list to append any created child-Permissions to, may be null
+ * @return Permission object
+ */
+ public static Permission loadPermission(String name, Map<String, Object> data, PermissionDefault def, List<Permission> output) {
if (name == null) {
throw new IllegalArgumentException("Name cannot be null");
}
if (data == null) {
throw new IllegalArgumentException("Data cannot be null");
}
String desc = null;
- PermissionDefault def = null;
Map<String, Boolean> children = null;
if (data.containsKey("default")) {
@@ -190,7 +275,7 @@ public static Permission loadPermission(String name, Map<String, Object> data) {
if (data.containsKey("children")) {
try {
- children = extractChildren(data);
+ children = extractChildren(data, name, def, output);
} catch (ClassCastException ex) {
throw new IllegalArgumentException("'children' key is of wrong type", ex);
}
@@ -204,19 +289,55 @@ public static Permission loadPermission(String name, Map<String, Object> data) {
}
}
- return new Permission(name, desc, def, children);
+ Permission result = new Permission(name, desc, def, children);
+
+ if (data.containsKey("parents")) {
+ try {
+ Object parents = data.get("parents");
+
+ if (parents instanceof String) {
+ result.addParent((String)parents, true);
+ }
+ } catch (ClassCastException ex) {
+ throw new IllegalArgumentException("'parents' key is of wrong type", ex);
+ }
+ }
+
+ return result;
}
- private static Map<String, Boolean> extractChildren(Map<String, Object> data) {
- Map<String, Boolean> input = (Map<String, Boolean>)data.get("children");
- Set<Entry<String, Boolean>> entries = input.entrySet();
- for (Map.Entry<String, Boolean> entry : entries) {
- if (!(entry.getValue() instanceof Boolean)) {
- throw new IllegalArgumentException("Child '" + entry.getKey() + "' contains invalid value");
+ private static Map<String, Boolean> extractChildren(Map<String, Object> data, String name, PermissionDefault def, List<Permission> output) {
+ Map<String, Object> input = (Map<String, Object>)data.get("children");
+ Map<String, Boolean> children = new LinkedHashMap();
+
+ for (Map.Entry<String, Object> entry : input.entrySet()) {
+ if ((entry.getValue() instanceof Boolean)) {
+ children.put(entry.getKey(), (Boolean)entry.getValue());
+ } else if ((entry.getValue() instanceof Map)) {
+ try {
+ System.out.println("Going to make new child " + (String)entry.getKey() + " perm for " + name);
+
+ try
+ {
+ Permission perm = loadPermission((String)entry.getKey(), (Map<String, Object>)entry.getValue(), def, output);
+ children.put(perm.getName(), Boolean.valueOf(true));
+
+ if (output != null) {
+ output.add(perm);
+ }
+ }
+ catch (Throwable ex) {
+ Bukkit.getServer().getLogger().log(Level.SEVERE, "Permission node '" + (String)entry.getKey() + "' in child of " + name + " is invalid", ex);
+ }
+ } catch (ClassCastException ex) {
+ throw new IllegalArgumentException("Child '" + (String)entry.getKey() + "' contains invalid map type");
+ }
+ } else {
+ throw new IllegalArgumentException("Child '" + (String)entry.getKey() + "' contains invalid value");
}
}
- return input;
+ return children;
}
}
@@ -5,11 +5,13 @@
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.permissions.Permission;
+import org.bukkit.permissions.PermissionDefault;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
@@ -29,7 +31,8 @@
private String website = null;
private boolean database = false;
private PluginLoadOrder order = PluginLoadOrder.POSTWORLD;
- private ArrayList<Permission> permissions = new ArrayList<Permission>();
+ private List<Permission> permissions = new ArrayList<Permission>();
+ private PermissionDefault defaultPerm = PermissionDefault.OP;
@SuppressWarnings("unchecked")
public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException {
@@ -143,10 +146,14 @@ public void setDatabaseEnabled(boolean database) {
this.database = database;
}
- public ArrayList<Permission> getPermissions() {
+ public List<Permission> getPermissions() {

This comment has been minimized.

Show comment
Hide comment
@ycros

ycros Sep 21, 2011

Okay, so while I totally sympathize with using List over ArrayList, this change has no impact on the functionality of the code, while it breaks backwards API compatability with any plugin trying to call this method. Now all plugins need to be recompiled against this version of Bukkit or later.

Also I've just reviewed all the recent commits, and this is the only one that breaks backwards compatibility.

@ycros

ycros Sep 21, 2011

Okay, so while I totally sympathize with using List over ArrayList, this change has no impact on the functionality of the code, while it breaks backwards API compatability with any plugin trying to call this method. Now all plugins need to be recompiled against this version of Bukkit or later.

Also I've just reviewed all the recent commits, and this is the only one that breaks backwards compatibility.

This comment has been minimized.

Show comment
Hide comment
@Cogito

Cogito Sep 21, 2011

Contributor

I wonder how many plugins are affected by this break. If the plugin defined their copy of the permissions variable as a List, or never stored the list, there should be no issues.

@Cogito

Cogito Sep 21, 2011

Contributor

I wonder how many plugins are affected by this break. If the plugin defined their copy of the permissions variable as a List, or never stored the list, there should be no issues.

This comment has been minimized.

Show comment
Hide comment
@ycros

ycros Sep 21, 2011

Well, anything that calls that method breaks. The signature has changed. A few of my plugins break now, I had to rollback to an older CB build.

@ycros

ycros Sep 21, 2011

Well, anything that calls that method breaks. The signature has changed. A few of my plugins break now, I had to rollback to an older CB build.

return permissions;
}
+ public PermissionDefault getPermissionDefault() {
+ return defaultPerm;
+ }
+
private void loadMap(Map<String, Object> map) throws InvalidDescriptionException {
try {
name = map.get("name").toString();
@@ -257,11 +264,21 @@ private void loadMap(Map<String, Object> map) throws InvalidDescriptionException
}
}
+ if (map.containsKey("default-permission")) {
+ try {
+ defaultPerm = defaultPerm.getByName((String)map.get("default-permission"));
+ } catch (ClassCastException ex) {
+ throw new InvalidDescriptionException(ex, "default-permission is of wrong type");
+ } catch (IllegalArgumentException ex) {
+ throw new InvalidDescriptionException(ex, "default-permission is not a valid choice");
+ }
+ }
+
if (map.containsKey("permissions")) {
try {
Map<String, Map<String, Object>> perms = (Map<String, Map<String, Object>>) map.get("permissions");
- loadPermissions(perms);
+ permissions = Permission.loadPermissions(perms, "Permission node '%s' in plugin description file for " + getFullName() + " is invalid", defaultPerm);
} catch (ClassCastException ex) {
throw new InvalidDescriptionException(ex, "permissions are of wrong type");
}
@@ -276,6 +293,7 @@ private void loadMap(Map<String, Object> map) throws InvalidDescriptionException
map.put("version", version);
map.put("database", database);
map.put("order", order.toString());
+ map.put("default-permission", defaultPerm.toString());
if (commands != null) {
map.put("command", commands);
@@ -301,16 +319,4 @@ private void loadMap(Map<String, Object> map) throws InvalidDescriptionException
return map;
}
-
- private void loadPermissions(Map<String, Map<String, Object>> perms) {
- Set<String> keys = perms.keySet();
-
- for (String name : keys) {
- try {
- permissions.add(Permission.loadPermission(name, perms.get(name)));
- } catch (Throwable ex) {
- Bukkit.getServer().getLogger().log(Level.SEVERE, "Permission node '" + name + "' in plugin description file for " + getFullName() + " is invalid", ex);
- }
- }
- }
}

0 comments on commit 326f2ac

Please sign in to comment.