/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.security;

import java.util.*;

/**
 * Represents a security role for a user within the Venice architecture.<P>
 * Venice uses a system of scoped security roles to govern access to various features.  Each role
 * has associated with it a <EM>security level</EM>, which is nominally a 16-bit unsigned integer
 * (but is represented in Java as an <CODE>int</CODE>).  Each access permission also has associated
 * with it an access level; if the user's granted level is greater than or equal to the access level,
 * access is granted.<P>
 * Access levels are arranged in <EM>scopes</EM>; if an object is logically contained within another
 * object, then its scope is greater than that of the containing object.  The system itself has
 * scope 0; communities use scope 3 by default; objects such as conferences (within communities) are
 * at scope 6.  The scope system is described further in {@link ScopeInfo}.<P>
 * Each role also has associated with it a human-readable name and a programmatic symbol.  The symbol
 * will usually be of the form "<EM>subsystem.name</EM>," such as "Global.Normal," "Community.Host,"
 * or "Conference.Member."<P>
 * Roles are created as part of a {@link SecurityMonitor}, such as {@link StaticSecurityMonitor}, and
 * are managed by it.
 *
 * @author Eric J. Bowersox &lt;erbo@silcom.com&gt;
 * @version X
 */
public final class Role implements Comparable, Cloneable
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private int level;                // access level in this role
  private String name;              // human-readable name
  private String symbol;            // programmatic symbol

  /*--------------------------------------------------------------------------------
   * Constructors
   *--------------------------------------------------------------------------------
   */

  /**
   * Creates a new instance of a <CODE>Role</CODE> object.
   *
   * @param level The level to encode in this role.
   * @param name The human-readable name of the role.
   * @param symbol The programmatic symbol of the role.
   * @see #create(int,java.lang.String,java.lang.String)
   */
  protected Role(int level, String name, String symbol)
  {
    this.level = level;
    this.name = name;
    this.symbol = symbol;

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Overrides from class Object
   *--------------------------------------------------------------------------------
   */

  /**
   * Tests this object for equality with another object.  Two <CODE>Role</CODE> objects are equivalent
   * iff the levels that they enclose are equal.
   *
   * @param obj The other object to compare to this one.
   * @return <CODE>true</CODE> if the two objects are equal.
   */
  public boolean equals(Object obj)
  {
    if (obj==null)
      return false;
    else if (obj==this)
      return true;
    if (obj instanceof Role)
    { // compare levels
      Role other = (Role)obj;
      return (level==other.level);

    } // end if

    return obj.toString().equals(toString());

  } // end equals

  /**
   * Returns a hash code that can be used as an index for this object in a hash table.  In keeping
   * with the definition of <CODE>equals</CODE>, a <CODE>Role</CODE>'s hash code is its level.
   *
   * @return The hash code for this object.
   * @see #equals(java.lang.Object)
   */
  public int hashCode()
  {
    return level;

  } // end hashCode

  /**
   * Returns a "debugging" string equivalent for this role.
   *
   * @return The string equivalent for this role.
   */
  public String toString()
  {
    StringBuffer buf = new StringBuffer(name);
    buf.append('[').append(level).append("]{").append(symbol).append('}');
    return buf.toString();

  } // end toString

  /*--------------------------------------------------------------------------------
   * Implementations from interface Comparable
   *--------------------------------------------------------------------------------
   */

  /**
   * Compares one <CODE>Role</CODE> object to another.  A <CODE>Role</CODE> is logically less
   * than another one if its enclosed level is less than the other one's enclosed level.
   *
   * @param obj The other role object to compare to.
   * @return A value less than 0 if this <CODE>Role</CODE> is logically "less than" the specified one; a
   *         value greater than 0 if this <CODE>Role</CODE> is logically "greater than" the other one; 0 if
   *         the two are equal.
   * @exception java.lang.ClassCastException If <CODE>obj</CODE> is not a <CODE>Role</CODE> object.
   */
  public int compareTo(Object obj)
  {
    if (obj==null)
      throw new NullPointerException("comparing a NULL object");
    if (!(obj instanceof Role))
      throw new ClassCastException("comparing non-Role to Role");
    Role other = (Role)obj;
    return level - other.level;

  } // end compareTo

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  /**
   * Returns the security level associated with this <CODE>Role</CODE>.
   *
   * @return The security level associated with this <CODE>Role</CODE>.
   */
  public final int getLevel()
  {
    return level;

  } // end getLevel

  /**
   * Returns the human-readable name associated with this <CODE>Role</CODE>.
   *
   * @return The human-readable name associated with this <CODE>Role</CODE>.
   */
  public final String getName()
  {
    return name;

  } // end getName

  /**
   * Returns the programmatic symbol associated with this <CODE>Role</CODE>.
   *
   * @return The programmatic symbol associated with this <CODE>Role</CODE>.
   */
  public final String getSymbol()
  {
    return symbol;

  } // end getSymbol

  /**
   * Returns <CODE>true</CODE> if the capability associated with this <CODE>Role</CODE> would
   * be satisfied by the specified security level, i.e. the parameter is greater than or equal to
   * the level associated with this role.
   *
   * @param l The level to test against this <CODE>Role</CODE>.
   * @return <CODE>true</CODE> if the role is satisfied by this level.
   */
  public final boolean isSatisfiedBy(int l)
  {
    return (l>=level);

  } // end isSatisfiedBy

  /*--------------------------------------------------------------------------------
   * External static operations
   *--------------------------------------------------------------------------------
   */

  /**
   * Creates a new <CODE>Role</CODE>.
   *
   * @param level The level to encode in this role.
   * @param name The human-readable name of the role.
   * @param symbol The programmatic symbol of the role.
   * @return The new associated <CODE>Role</CODE> object.
   */
  static final Role create(int level, String name, String symbol)
  {
    return new Role(level,name,symbol);

  } // end create

} // end class Role
