Newer
Older
ultramine_permissions / src / main / java / org / ultramine / permission / PermissionRepository.java
@vlad20012 vlad20012 on 2 May 2017 5 KB Initial commit
package org.ultramine.permission;

import org.ultramine.permission.internal.AbstractResolver;
import org.ultramine.permission.internal.CheckResult;
import org.ultramine.permission.internal.MetaResolver;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PermissionRepository
{
	private final Map<String, ProxyPermission> proxyPermissions;
	private final Map<String, IPermissionContainer> proxyContainers;

	public PermissionRepository()
	{
		proxyPermissions = new HashMap<String, ProxyPermission>();
		proxyContainers = new HashMap<String, IPermissionContainer>();
	}

	public PermissionRepository(PermissionRepository anotherRepository)
	{
		proxyPermissions = new HashMap<String, ProxyPermission>(anotherRepository.proxyPermissions);
		proxyContainers = new HashMap<String, IPermissionContainer>(anotherRepository.proxyContainers);
	}

	public ProxyPermission getPermission(String key)
	{
		key = key.toLowerCase();

		ProxyPermission permission = proxyPermissions.get(key);
		if (permission == null)
		{
			if (key.startsWith("^"))
				permission = new NegativePermission(key, getPermission(key.substring(1)));

			else if (key.endsWith(".*") || key.equals("*"))
				permission = new ProxyPermission(new DummyPermission(key));

			else
				permission = new ProxyPermission(key);

			proxyPermissions.put(key, permission);
		}

		return permission;
	}

	public ProxyPermission registerPermission(IPermission permission)
	{
		ProxyPermission proxy = getPermission(permission.getKey());
		if (!proxy.isDummy())
			throw new IllegalArgumentException("Permission already registered");

		if (permission instanceof ProxyPermission)
		{
			proxyPermissions.put(permission.getKey(), (ProxyPermission)permission);
			return (ProxyPermission)permission;
		}
		else
		{
			proxy.link(permission);
			return proxy;
		}
	}

	public void lockPermissions(String... permissions)
	{
		for (String permission : permissions)
			getPermission(permission).lock();
	}
	
	public IPermissionContainer getContainer(String name)
	{
		IPermissionContainer container = proxyContainers.get(name);
		if(container == null)
			proxyContainers.put(name, container = new ProxyContainer(name));
		return container;
	}
	
	public void registerContainer(String name, IPermissionContainer container)
	{
		IPermissionContainer old = proxyContainers.get(name);
		if(old == null)
			proxyContainers.put(name, container);
		else if(old instanceof ProxyContainer)
			((ProxyContainer)old).link(container);
		else
			throw new IllegalArgumentException("Container already registered");
			
	}

	public static class ProxyPermission implements IPermission
	{
		private IPermission wrappedPermission;
		private boolean isDummy;
		private List<IDirtyListener> listeners;

		public ProxyPermission(String key)
		{
			this.wrappedPermission = new DummyPermission(key);
			this.isDummy = true;
			listeners = new ArrayList<IDirtyListener>();
		}

		public ProxyPermission(IPermission permission)
		{
			this.wrappedPermission = permission;
			this.isDummy = false;
		}

		@Override
		public String getKey()
		{
			return wrappedPermission.getKey();
		}

		public IPermission getWrappedPermission()
		{
			return wrappedPermission;
		}

		public boolean isDummy()
		{
			return isDummy;
		}

		@Override
		public CheckResult check(String key)
		{
			return wrappedPermission.check(key);
		}

		@Override
		public String getMeta(String key)
		{
			return wrappedPermission.getMeta(key);
		}

		@Override
		public void mergePermissionsTo(AbstractResolver<Boolean> resolver)
		{
			wrappedPermission.mergePermissionsTo(resolver);
		}

		@Override
		public void mergeMetaTo(MetaResolver resolver)
		{
			wrappedPermission.mergeMetaTo(resolver);
		}

		@Override
		public void subscribe(IDirtyListener listener)
		{
			if (isDummy)
				listeners.add(listener);
			else
				wrappedPermission.subscribe(listener);
		}

		@Override
		public void unsubscribe(IDirtyListener listener)
		{
			if (isDummy)
				listeners.remove(listener);
			else
				wrappedPermission.unsubscribe(listener);
		}

		private void lock()
		{
			listeners = null;
			isDummy = false;
		}

		private void link(IPermission permission)
		{
			wrappedPermission = permission;
			for (IDirtyListener listener : listeners)
			{
				permission.subscribe(listener);
				listener.makeDirty();
			}
			lock();
		}

		@Override
		public int hashCode()
		{
			return wrappedPermission.hashCode();
		}

		@Override
		public boolean equals(Object obj)
		{
			return wrappedPermission.equals(obj);
		}

		@Override
		public String toString()
		{
			return wrappedPermission.toString();
		}
	}

	private static class ProxyContainer implements IPermissionContainer
	{
		private final String name;
		private IPermissionContainer wrappedContainer;
		
		private ProxyContainer(String name)
		{
			this.name = name;
		}
	
		@Override
		public String getName()
		{
			return name;
		}
		
		@Override
		public CheckResult check(String worldname, String permissionKey)
		{
			return wrappedContainer != null ? wrappedContainer.check(worldname, permissionKey) : CheckResult.UNRESOLVED;
		}
		
		@Override
		public String getMeta(String worldname, String key)
		{
			return wrappedContainer != null ? wrappedContainer.getMeta(worldname, key) : null;
		}
	
		private void link(IPermissionContainer container)
		{
			this.wrappedContainer = container;
		}
	}
}