001    package org.bukkit.permissions;
002    
003    import java.util.LinkedHashMap;
004    import java.util.Map;
005    import org.bukkit.plugin.Plugin;
006    
007    /**
008     * Holds information about a permission attachment on a {@link Permissible}
009     * object
010     */
011    public class PermissionAttachment {
012        private PermissionRemovedExecutor removed;
013        private final Map<String, Boolean> permissions = new LinkedHashMap<String, Boolean>();
014        private final Permissible permissible;
015        private final Plugin plugin;
016    
017        public PermissionAttachment(Plugin plugin, Permissible Permissible) {
018            if (plugin == null) {
019                throw new IllegalArgumentException("Plugin cannot be null");
020            } else if (!plugin.isEnabled()) {
021                throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
022            }
023    
024            this.permissible = Permissible;
025            this.plugin = plugin;
026        }
027    
028        /**
029         * Gets the plugin responsible for this attachment
030         *
031         * @return Plugin responsible for this permission attachment
032         */
033        public Plugin getPlugin() {
034            return plugin;
035        }
036    
037        /**
038         * Sets an object to be called for when this attachment is removed from a
039         * {@link Permissible}. May be null.
040         *
041         * @param ex Object to be called when this is removed
042         */
043        public void setRemovalCallback(PermissionRemovedExecutor ex) {
044            removed = ex;
045        }
046    
047        /**
048         * Gets the class that was previously set to be called when this
049         * attachment was removed from a {@link Permissible}. May be null.
050         *
051         * @return Object to be called when this is removed
052         */
053        public PermissionRemovedExecutor getRemovalCallback() {
054            return removed;
055        }
056    
057        /**
058         * Gets the Permissible that this is attached to
059         *
060         * @return Permissible containing this attachment
061         */
062        public Permissible getPermissible() {
063            return permissible;
064        }
065    
066        /**
067         * Gets a copy of all set permissions and values contained within this
068         * attachment.
069         * <p>
070         * This map may be modified but will not affect the attachment, as it is a
071         * copy.
072         *
073         * @return Copy of all permissions and values expressed by this attachment
074         */
075        public Map<String, Boolean> getPermissions() {
076            return new LinkedHashMap<String, Boolean>(permissions);
077        }
078    
079        /**
080         * Sets a permission to the given value, by its fully qualified name
081         *
082         * @param name Name of the permission
083         * @param value New value of the permission
084         */
085        public void setPermission(String name, boolean value) {
086            permissions.put(name.toLowerCase(), value);
087            permissible.recalculatePermissions();
088        }
089    
090        /**
091         * Sets a permission to the given value
092         *
093         * @param perm Permission to set
094         * @param value New value of the permission
095         */
096        public void setPermission(Permission perm, boolean value) {
097            setPermission(perm.getName(), value);
098        }
099    
100        /**
101         * Removes the specified permission from this attachment.
102         * <p>
103         * If the permission does not exist in this attachment, nothing will
104         * happen.
105         *
106         * @param name Name of the permission to remove
107         */
108        public void unsetPermission(String name) {
109            permissions.remove(name.toLowerCase());
110            permissible.recalculatePermissions();
111        }
112    
113        /**
114         * Removes the specified permission from this attachment.
115         * <p>
116         * If the permission does not exist in this attachment, nothing will
117         * happen.
118         *
119         * @param perm Permission to remove
120         */
121        public void unsetPermission(Permission perm) {
122            unsetPermission(perm.getName());
123        }
124    
125        /**
126         * Removes this attachment from its registered {@link Permissible}
127         *
128         * @return true if the permissible was removed successfully, false if it
129         *     did not exist
130         */
131        public boolean remove() {
132            try {
133                permissible.removeAttachment(this);
134                return true;
135            } catch (IllegalArgumentException ex) {
136                return false;
137            }
138        }
139    }