JmxPermissions.java

package com.ziesemer.utils.jmx.server.authorization;

import java.security.Permission;
import java.security.PermissionCollection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * <p>This class is <em>not</em> thread-safe for modifications.
 * 	The intended use is to populate the collection, then call {@link #setReadOnly()},
 * 		after which it may be used freely across multiple threads.</p>
 * @author Mark A. Ziesemer
 * 	<a href="http://www.ziesemer.com.">&lt;www.ziesemer.com&gt;</a>
 */
public class JmxPermissions extends PermissionCollection{
	
	private static final long serialVersionUID = 1L;
	
	protected final Set<JmxPermission> permSet = new HashSet<JmxPermission>();
	protected final Set<JmxPermission> readOnlyPermSet = Collections.unmodifiableSet(permSet);
	
	@Override
	public void add(final Permission permission){
		if(!(permission instanceof JmxPermission)){
			throw new IllegalArgumentException("Invalid permission: " + permission);
		}
		if(isReadOnly()){
			throw new SecurityException("Attempt to add a Permission to a read-only PermissionCollection.");
		}
		permSet.add((JmxPermission)permission);
	}
	
	@Override
	public Enumeration<Permission> elements(){
		// Unfortunately, java.util.Collections.enumeration(...) doesn't work
		// 	due to not accepting extended generic types:
		// return Collections.enumeration(permSet);
		return new Enumeration<Permission>(){
			protected Iterator<? extends Permission> i = permSet.iterator();
			public boolean hasMoreElements(){
				return i.hasNext();
			}
			public Permission nextElement(){
				return i.next();
			}
		};
	}
	
	@Override
	public boolean implies(final Permission permission){
		for(final Permission p : permSet){
			if(p.implies(permission)){
				return true;
			}
		}
		return false;
	}
	
	public Set<JmxPermission> getAsReadOnlySet(){
		return readOnlyPermSet;
	}
	
}