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     */
019    package org.apache.wiki.auth;
020    
021    import java.io.Serializable;
022    import java.security.Principal;
023    import java.util.Arrays;
024    import java.util.Comparator;
025    
026    /**
027     *  A lightweight, immutable Principal class. WikiPrincipals can be created with
028     *  and optional "type" to denote what type of user profile Principal it represents
029     *  (FULL_NAME, WIKI_NAME, LOGIN_NAME). Types are used to determine suitable
030     *  user and login Principals in classes like WikiSession. However, the type
031     *  property of a WikiPrincipal does not affect a WikiPrincipal's logical equality
032     *  or hash code; two WikiPrincipals with the same name but different types are still
033     *  considered equal.
034     *
035     *  @since  2.2
036     */
037    public 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
043         * created with an optional type designator: 
044         * LOGIN_NAME, WIKI_NAME, FULL_NAME or UNSPECIFIED.
045         */
046        public static final Principal GUEST = new WikiPrincipal( "Guest" );
047    
048        /** WikiPrincipal type denoting a user's full name. */
049        public static final String FULL_NAME  = "fullName";
050        
051        /** WikiPrincipal type denoting a user's login name. */
052        public static final String LOGIN_NAME = "loginName";
053        
054        /** WikiPrincipal type denoting a user's wiki name. */
055        public static final String WIKI_NAME  = "wikiName";
056        
057        /** Generic WikiPrincipal of unspecified type. */
058        public static final String UNSPECIFIED  = "unspecified";
059        
060        /** Static instance of Comparator that allows Principals to be sorted. */
061        public static final Comparator<Principal> COMPARATOR = new PrincipalComparator();
062        
063        private static final String[] VALID_TYPES;
064        
065        static
066        {
067            VALID_TYPES = new String[] { FULL_NAME, LOGIN_NAME, WIKI_NAME, UNSPECIFIED };
068            Arrays.sort( VALID_TYPES );
069        }
070    
071        private final String          m_name;
072        private final String          m_type;
073    
074        /** For serialization purposes */
075        protected WikiPrincipal()
076        {
077            this(null);
078        }
079        
080        /**
081         * Constructs a new WikiPrincipal with a given name and a type of
082         * {@link #UNSPECIFIED}.
083         * @param name the name of the Principal
084         */
085        public WikiPrincipal( String name )
086        {
087            m_name = name;
088            m_type = UNSPECIFIED;
089        }
090        
091        /**
092         * Constructs a new WikiPrincipal with a given name and optional type
093         * designator. If the supplied <code>type</code> parameter is not
094         * {@link #LOGIN_NAME}, {@link #FULL_NAME}, {@link #WIKI_NAME}
095         * or {@link #WIKI_NAME}, this method throws
096         * an {@link IllegalArgumentException}.
097         * @param name the name of the Principal
098         * @param type the type for this principal, which may be {@link #LOGIN_NAME},
099         *            {@link #FULL_NAME}, {@link #WIKI_NAME} or {@link #WIKI_NAME}.
100         */
101        public WikiPrincipal( String name, String type )
102        {
103            m_name = name;
104            if ( Arrays.binarySearch( VALID_TYPES, type ) < 0 )
105            {
106                throw new IllegalArgumentException( "Principal type '" + type + "' is invalid.");
107            }
108            m_type = type;
109        }
110    
111        /**
112         *  Returns the wiki name of the Principal.
113         *  @return the name
114         */
115        public String getName()
116        {
117            return m_name;
118        }
119    
120        /**
121         * Two <code>WikiPrincipal</code>s are considered equal if their
122         * names are equal (case-sensitive).
123         * @param obj the object to compare
124         * @return the result of the equality test
125         */
126        public boolean equals( Object obj )
127        {
128            if ( obj == null || !( obj instanceof WikiPrincipal ) )
129            {
130                return false;
131            }
132            return m_name.equals( ( (WikiPrincipal) obj ).getName() );
133        }
134    
135        /**
136         *  The hashCode() returned for the WikiPrincipal is the same as
137         *  for its name.
138         *  @return the hash code
139         */
140        public int hashCode()
141        {
142            return m_name.hashCode();
143        }
144        
145        /**
146         * Returns the Principal "type": {@link #LOGIN_NAME}, {@link #FULL_NAME},
147         * {@link #WIKI_NAME} or {@link #WIKI_NAME}
148         * @return the type
149         */
150        public String getType()
151        {
152            return m_type;
153        }
154        
155        /**
156         * Returns a human-readable representation of the object.
157         * @return the string representation
158         */
159        public String toString()
160        {
161            return "[WikiPrincipal (" + m_type + "): " + getName() + "]";
162        }
163    
164        /**
165         *  Allows comparisons to any other Principal objects.  Primary sorting
166         *  order is by the principal name, as returned by getName().
167         *  
168         *  @param o {@inheritDoc}
169         *  @return {@inheritDoc}
170         *  @since 2.7.0
171         */
172        public int compareTo(Principal o)
173        {
174            return getName().compareTo( o.getName() );
175        }
176        
177    
178    }