Permissions.java 5.06 KB
Newer Older
Matt Tucker's avatar
Matt Tucker committed
1 2 3 4 5
/**
 * $RCSfile$
 * $Revision$
 * $Date$
 *
Matt Tucker's avatar
Matt Tucker committed
6
 * Copyright (C) 2004 Jive Software. All rights reserved.
Matt Tucker's avatar
Matt Tucker committed
7
 *
Matt Tucker's avatar
Matt Tucker committed
8 9
 * This software is published under the terms of the GNU Public License (GPL),
 * a copy of which is included in this distribution.
Matt Tucker's avatar
Matt Tucker committed
10
 */
Matt Tucker's avatar
Matt Tucker committed
11

Matt Tucker's avatar
Matt Tucker committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
package org.jivesoftware.messenger.auth;

import org.jivesoftware.util.CacheSizes;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.Cacheable;

/**
 * Represents a set of permissions that an entity has for an object in the system. For example,
 * the rights that a user has for a category. Permissions are used by the protection proxy objects
 * defined for each major component of the system to provide access rights.<p>
 * <p/>
 * A Permissions object is internally represented as a long with each bit indicating whether
 * a particular permission is set. The constants defined by extensions of this class define the bit
 * masks that can be used for permission operations. For example, the following code creates
 * permissions:<pre>
 * <p/>
 * // Create a permissions object with only read permissions set to true.
 * Permissions perms1 = new Permissions(ForumPermissions.READ_FORUM);
 * // Create a permissions object with read and system admin permissions set to true.
 * Permissions perms2 = new Permissions(ForumPermissions.READ_FORUM |
 *          ForumPermissions.SYSTEM_ADMIN);</pre>
 * <p/>
 * If we were to view the bits of each variable, <tt>perms1</tt> would be
 * <tt>0000000000000000000000000000000000000000000000000000000000000001</tt> and
 * <tt>perms2</tt> would be
 * <tt>0000000000000000000000000000000010000000000000000000000000000001</tt>.<p>
 *
 * @author Matt Tucker
 */
public class Permissions implements Cacheable {

    /**
     * No permissions.
     */
    public static final long NONE = 0x000000000000000L;

    /**
     * Permission to see the online status of a particular user.
     */
    public static final long VIEW_ONLINE_STATUS = 0x100000000000000L;

    /**
     * Permission to administer a particular user.
     */
    public static final long USER_ADMIN = 0x200000000000000L;

    /**
     * Permission to administer a particular group.
     */
    public static final long GROUP_ADMIN = 0x400000000000000L;

    /**
     * Permission to administer the entire sytem.
     */
    public static final long SYSTEM_ADMIN = 0x800000000000000L;

    /**
     * Permission to modify a queue.
     */
    public static final long QUEUE_ADMIN = 0x1000000000000000L;

    /**
     * A long holding permission values. We use the bits in the number to extract up to 63
     * different permissions.
     */
    private long permissions;

    /**
     * Create a new permissions object with the specified permissions.
     *
     * @param permissions integer bitmask values to for the new Permissions.
     */
    public Permissions(long permissions) {
        this.permissions = permissions;
    }

    /**
     * Creates a new ForumPermission object by combining two permissions
     * objects. The higher permission of each permission type will be used.
     *
     * @param permissions1 the first permissions to use when creating the new Permissions.
     * @param permissions2 the second permissions to use when creating the new Permissions.
     */
    public Permissions(Permissions permissions1, Permissions permissions2) {
        permissions = permissions1.permissions | permissions2.permissions;
    }

    /**
     * Returns true if one or more of the permission types is set to true.
     *
     * @param permissionTypes
     * @return true if one or more of the permission types is set to true, false otherwise.
     */
    public boolean hasPermission(long permissionTypes) {
        return (permissions & permissionTypes) != 0;
    }

    /**
     * Sets the permissions given by a bit mask to true or false. For example, the following
     * would set the READ_FORUM and SYSTEM_ADMIN permissions to true:
     * <p/>
     * <pre>
     * permissions.set(ForumPermissions.READ_FORUM | ForumPermissions.SYSTEM_ADMIN, true);
     * </pre>
     *
     * @param permissionTypes the permission types to set.
     * @param value           true to enable the permission, false to disable.
     */
    public void set(long permissionTypes, boolean value) {
        if (value) {
            permissions = permissions | permissionTypes;
        }
        else {
            permissionTypes = ~permissionTypes;
            permissions = permissions & permissionTypes;
        }
    }

    /**
     * Returns the long value (bitmask) of the permissions that are set.
     *
     * @return the long value of the object.
     */
    public long value() {
        return permissions;
    }

    public String toString() {
        return StringUtils.zeroPadString(Long.toBinaryString(permissions), 63);
    }

    // Cacheable Interface

    public int getCachedSize() {
        // Approximate the size of the object in bytes by calculating the size
        // of each field.
        int size = 0;
        size += CacheSizes.sizeOfObject();                 // overhead of object
        size += CacheSizes.sizeOfLong();                   // permissions bits
        return size;
    }
}