/* * The MIT License * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package hudson.security; import hudson.model.Hudson; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.annotation.CheckForNull; import org.jvnet.localizer.Localizable; /** * Group of {@link Permission}s that share the same {@link Permission#owner owner}. * * Sortable by the owner class name. */ public final class PermissionGroup implements Iterable<Permission>, Comparable<PermissionGroup> { private final SortedSet<Permission> permissions = new TreeSet<Permission>(Permission.ID_COMPARATOR); public final Class owner; /** * Human readable title of this permission group. * This should be short. */ public final Localizable title; /** * Both creates a registers a new permission group. * @param owner sets {@link #owner} * @param title sets {@link #title} * @throws IllegalStateException if this group was already registered */ public PermissionGroup(Class owner, Localizable title) throws IllegalStateException { this.owner = owner; this.title = title; register(this); } private String id() { return owner.getName(); } public Iterator<Permission> iterator() { return getPermissions().iterator(); } /*package*/ synchronized void add(Permission p) { if (!permissions.add(p)) { throw new IllegalStateException("attempt to register a second Permission for " + p.getId()); } } /** * Lists up all the permissions in this group. */ public synchronized List<Permission> getPermissions() { return new ArrayList<Permission>(permissions); } public synchronized boolean hasPermissionContainedBy(PermissionScope scope) { for (Permission p : permissions) if (p.isContainedBy(scope)) return true; return false; } /** * Finds a permission that has the given name. */ public synchronized Permission find(String name) { for (Permission p : permissions) { if(p.name.equals(name)) return p; } return null; } public int compareTo(PermissionGroup that) { // first, sort by the 'compare order' number. This is so that // we can put Hudson.PERMISSIONS first. int r= this.compareOrder()-that.compareOrder(); if(r!=0) return r; // among the permissions of the same group, just sort by their names // so that the sort order is consistent regardless of classloading order. return id().compareTo(that.id()); } private int compareOrder() { if(owner==Hudson.class) return 0; return 1; } @Override public boolean equals(Object o) { return o instanceof PermissionGroup && id().equals(((PermissionGroup) o).id()); } @Override public int hashCode() { return id().hashCode(); } public synchronized int size() { return permissions.size(); } @Override public String toString() { return "PermissionGroup[" + id() + "]"; } private static synchronized void register(PermissionGroup g) { if (!PERMISSIONS.add(g)) { throw new IllegalStateException("attempt to register a second PermissionGroup for " + g.id()); } } /** * Returns all the {@link PermissionGroup}s available in the system. * @return * always non-null. Read-only. */ public static synchronized List<PermissionGroup> getAll() { return new ArrayList<PermissionGroup>(PERMISSIONS); } /** * Gets the {@link PermissionGroup} whose {@link PermissionGroup#owner} is the given class. * * @return null if not found. */ public static synchronized @CheckForNull PermissionGroup get(Class owner) { for (PermissionGroup g : PERMISSIONS) { if (g.owner == owner) { return g; } } return null; } /** * All the permissions in the system, keyed by their owners. */ private static final SortedSet<PermissionGroup> PERMISSIONS = new TreeSet<PermissionGroup>(); }