    001/*
    002    Licensed to the Apache Software Foundation (ASF) under one
    003    or more contributor license agreements.  See the NOTICE file
    004    distributed with this work for additional information
    005    regarding copyright ownership.  The ASF licenses this file
    006    to you under the Apache License, Version 2.0 (the
    007    "License"); you may not use this file except in compliance
    008    with the License.  You may obtain a copy of the License at
    009
    010       http://www.apache.org/licenses/LICENSE-2.0
    011
    012    Unless required by applicable law or agreed to in writing,
    013    software distributed under the License is distributed on an
    014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015    KIND, either express or implied.  See the License for the
    016    specific language governing permissions and limitations
    017    under the License.
    018 */
    019package org.apache.wiki.auth;
    020
    021import org.apache.wiki.util.comparators.PrincipalComparator;
    022
    023import java.io.Serializable;
    024import java.security.Principal;
    025import java.util.Arrays;
    026import java.util.Comparator;
    027
    028
    029/**
    030 *  A lightweight, immutable Principal class. WikiPrincipals can be created with and optional "type" to denote what type of user
    031 *  profile Principal it represents (FULL_NAME, WIKI_NAME, LOGIN_NAME). Types are used to determine suitable user and login Principals in
    032 *  classes like Session. However, the type property of a WikiPrincipal does not affect a WikiPrincipal's logical equality
    033 *  or hash code; two WikiPrincipals with the same name but different types are still considered equal.
    034 *
    035 *  @since  2.2
    036 */
    037public final class WikiPrincipal implements Principal, Comparable< Principal >, Serializable {
    038
    039    private static final long serialVersionUID = 1L;
    040
    041    /**
    042     * Represents an anonymous user. WikiPrincipals may be created with an optional type designator:
    043     * LOGIN_NAME, WIKI_NAME, FULL_NAME or UNSPECIFIED.
    044     */
    045    public static final Principal GUEST = new WikiPrincipal( "Guest" );
    046
    047    /** WikiPrincipal type denoting a user's full name. */
    048    public static final String FULL_NAME = "fullName";
    049
    050    /** WikiPrincipal type denoting a user's login name. */
    051    public static final String LOGIN_NAME = "loginName";
    052
    053    /** WikiPrincipal type denoting a user's wiki name. */
    054    public static final String WIKI_NAME = "wikiName";
    055
    056    /** Generic WikiPrincipal of unspecified type. */
    057    public static final String UNSPECIFIED = "unspecified";
    058
    059    /** Static instance of Comparator that allows Principals to be sorted. */
    060    public static final Comparator< Principal > COMPARATOR = new PrincipalComparator();
    061
    062    private static final String[] VALID_TYPES;
    063
    064    static {
    065        VALID_TYPES = new String[] { FULL_NAME, LOGIN_NAME, WIKI_NAME, UNSPECIFIED };
    066        Arrays.sort( VALID_TYPES );
    067    }
    068
    069    private final String m_name;
    070    private final String m_type;
    071
    072    /** For serialization purposes */
    073    WikiPrincipal()
    074    {
    075        this(null);
    076    }
    077
    078    /**
    079     * Constructs a new WikiPrincipal with a given name and a type of {@link #UNSPECIFIED}.
    080     *
    081     * @param name the name of the Principal
    082     */
    083    public WikiPrincipal( final String name ) {
    084        m_name = name;
    085        m_type = UNSPECIFIED;
    086    }
    087
    088    /**
    089     * Constructs a new WikiPrincipal with a given name and optional type designator. If the supplied <code>type</code> parameter is not
    090     * {@link #LOGIN_NAME}, {@link #FULL_NAME}, {@link #WIKI_NAME} or {@link #WIKI_NAME}, this method throws
    091     * an {@link IllegalArgumentException}.
    092     *
    093     * @param name the name of the Principal
    094     * @param type the type for this principal, which may be {@link #LOGIN_NAME}, {@link #FULL_NAME}, {@link #WIKI_NAME} or {@link #WIKI_NAME}.
    095     */
    096    public WikiPrincipal( final String name, final String type ) {
    097        m_name = name;
    098        if( Arrays.binarySearch( VALID_TYPES, type ) < 0 ) {
    099            throw new IllegalArgumentException( "Principal type '" + type + "' is invalid." );
    100        }
    101        m_type = type;
    102    }
    103
    104    /**
    105     * Returns the wiki name of the Principal.
    106     *
    107     * @return the name
    108     */
    109    @Override
    110    public String getName() {
    111        return m_name;
    112    }
    113
    114    /**
    115     * Two <code>WikiPrincipal</code>s are considered equal if their names are equal (case-sensitive).
    116     *
    117     * @param obj the object to compare
    118     * @return the result of the equality test
    119     */
    120    @Override
    121    public boolean equals( final Object obj ) {
    122        if( !( obj instanceof WikiPrincipal ) ) {
    123            return false;
    124        }
    125        return m_name.equals( ( ( WikiPrincipal )obj ).getName() );
    126    }
    127
    128    /**
    129     *  The hashCode() returned for the WikiPrincipal is the same as for its name.
    130     *
    131     *  @return the hash code
    132     */
    133    @Override
    134    public int hashCode() {
    135        return m_name.hashCode();
    136    }
    137
    138    /**
    139     * Returns the Principal "type": {@link #LOGIN_NAME}, {@link #FULL_NAME}, {@link #WIKI_NAME} or {@link #WIKI_NAME}
    140     *
    141     * @return the type
    142     */
    143    public String getType()
    144    {
    145        return m_type;
    146    }
    147
    148    /**
    149     * Returns a human-readable representation of the object.
    150     *
    151     * @return the string representation
    152     */
    153    @Override
    154    public String toString() {
    155        return "[WikiPrincipal (" + m_type + "): " + getName() + "]";
    156    }
    157
    158    /**
    159     *  Allows comparisons to any other Principal objects.  Primary sorting order is by the principal name, returned by getName(), as
    160     *  defined by {@link PrincipalComparator}.
    161     *
    162     *  {@inheritDoc}
    163     *  @since 2.7.0
    164     */
    165    @Override
    166    public int compareTo( final Principal o ) {
    167        return COMPARATOR.compare( this, o );
    168    }
    169
    170}