package org.bukkit.permissions;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
/**
* Base Permissible for use in any Permissible object via proxy or extension
*/
public class PermissibleBase implements Permissible
{
private ServerOperator opable = null;
private Permissible parent = this;
private final List<PermissionAttachment> attachments = new LinkedList<PermissionAttachment>();
private final Map<String, PermissionAttachmentInfo> permissions = new HashMap<String, PermissionAttachmentInfo>();
public PermissibleBase(ServerOperator opable)
{
this.opable = opable;
if(opable instanceof Permissible)
{
this.parent = (Permissible) opable;
}
recalculatePermissions();
}
public boolean isOp()
{
if(opable == null)
{
return false;
}
else
{
return opable.isOp();
}
}
public void setOp(boolean value)
{
if(opable == null)
{
throw new UnsupportedOperationException("Cannot change op value as no ServerOperator is set");
}
else
{
opable.setOp(value);
}
}
public boolean isPermissionSet(String name)
{
if(name == null)
{
throw new IllegalArgumentException("Permission name cannot be null");
}
return permissions.containsKey(name.toLowerCase());
}
public boolean isPermissionSet(Permission perm)
{
if(perm == null)
{
throw new IllegalArgumentException("Permission cannot be null");
}
return isPermissionSet(perm.getName());
}
public boolean hasPermission(String inName)
{
if(inName == null)
{
throw new IllegalArgumentException("Permission name cannot be null");
}
String name = inName.toLowerCase();
if(isPermissionSet(name))
{
return permissions.get(name).getValue();
}
else
{
Permission perm = Bukkit.getServer().getPluginManager().getPermission(name);
if(perm != null)
{
return perm.getDefault().getValue(isOp());
}
else
{
return Permission.DEFAULT_PERMISSION.getValue(isOp());
}
}
}
public boolean hasPermission(Permission perm)
{
if(perm == null)
{
throw new IllegalArgumentException("Permission cannot be null");
}
String name = perm.getName().toLowerCase();
if(isPermissionSet(name))
{
return permissions.get(name).getValue();
}
return perm.getDefault().getValue(isOp());
}
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value)
{
if(name == null)
{
throw new IllegalArgumentException("Permission name cannot be null");
}
else if(plugin == null)
{
throw new IllegalArgumentException("Plugin cannot be null");
}
else if(!plugin.isEnabled())
{
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
}
PermissionAttachment result = addAttachment(plugin);
result.setPermission(name, value);
recalculatePermissions();
return result;
}
public PermissionAttachment addAttachment(Plugin plugin)
{
if(plugin == null)
{
throw new IllegalArgumentException("Plugin cannot be null");
}
else if(!plugin.isEnabled())
{
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
}
PermissionAttachment result = new PermissionAttachment(plugin, parent);
attachments.add(result);
recalculatePermissions();
return result;
}
public void removeAttachment(PermissionAttachment attachment)
{
if(attachment == null)
{
throw new IllegalArgumentException("Attachment cannot be null");
}
if(attachments.contains(attachment))
{
attachments.remove(attachment);
PermissionRemovedExecutor ex = attachment.getRemovalCallback();
if(ex != null)
{
ex.attachmentRemoved(attachment);
}
recalculatePermissions();
}
else
{
throw new IllegalArgumentException("Given attachment is not part of Permissible object " + parent);
}
}
public void recalculatePermissions()
{
clearPermissions();
Set<Permission> defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp());
Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent);
for(Permission perm : defaults)
{
String name = perm.getName().toLowerCase();
permissions.put(name, new PermissionAttachmentInfo(parent, name, null, true));
Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
calculateChildPermissions(perm.getChildren(), false, null);
}
for(PermissionAttachment attachment : attachments)
{
calculateChildPermissions(attachment.getPermissions(), false, attachment);
}
}
public synchronized void clearPermissions()
{
Set<String> perms = permissions.keySet();
for(String name : perms)
{
Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, parent);
}
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, parent);
Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, parent);
permissions.clear();
}
private void calculateChildPermissions(Map<String, Boolean> children, boolean invert, PermissionAttachment attachment)
{
Set<String> keys = children.keySet();
for(String name : keys)
{
Permission perm = Bukkit.getServer().getPluginManager().getPermission(name);
boolean value = children.get(name) ^ invert;
String lname = name.toLowerCase();
permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value));
Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent);
if(perm != null)
{
calculateChildPermissions(perm.getChildren(), !value, attachment);
}
}
}
public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks)
{
if(name == null)
{
throw new IllegalArgumentException("Permission name cannot be null");
}
else if(plugin == null)
{
throw new IllegalArgumentException("Plugin cannot be null");
}
else if(!plugin.isEnabled())
{
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
}
PermissionAttachment result = addAttachment(plugin, ticks);
if(result != null)
{
result.setPermission(name, value);
}
return result;
}
public PermissionAttachment addAttachment(Plugin plugin, int ticks)
{
if(plugin == null)
{
throw new IllegalArgumentException("Plugin cannot be null");
}
else if(!plugin.isEnabled())
{
throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled");
}
PermissionAttachment result = addAttachment(plugin);
if(Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), ticks) == -1)
{
Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1");
result.remove();
return null;
}
else
{
return result;
}
}
public Set<PermissionAttachmentInfo> getEffectivePermissions()
{
return new HashSet<PermissionAttachmentInfo>(permissions.values());
}
private class RemoveAttachmentRunnable implements Runnable
{
private PermissionAttachment attachment;
public RemoveAttachmentRunnable(PermissionAttachment attachment)
{
this.attachment = attachment;
}
public void run()
{
attachment.remove();
}
}
}