001/*
002 *  Copyright 2012 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.core.user;
017
018import java.time.ZonedDateTime;
019import java.util.stream.Collectors;
020import java.util.stream.Stream;
021
022import org.apache.commons.lang3.StringUtils;
023
024import org.ametys.core.user.directory.UserDirectory;
025import org.ametys.core.util.SizeUtils.ExcludeFromSizeCalculation;
026
027/**
028 * Implementation of the principal abstraction to represent an user with a login
029 * and eventually a fullname and an email.
030 */
031public class User implements java.security.Principal
032{
033    /**
034     * The identity of this principal.
035     */
036    protected UserIdentity _identity;
037
038    /**
039     * The last name of this principal.
040     */
041    protected String _lastName;
042    
043    /**
044     * The first name of this principal.
045     */
046    protected String _firstName;
047
048    /**
049     * The email of this principal.
050     */
051    protected String _email;
052    
053    /**
054     * The creation date
055     */
056    protected ZonedDateTime _creationDate;
057    
058    /**
059     * The creation origin
060     */
061    protected UserCreationOrigin _creationOrigin;
062    
063    /**
064     * The user directory this user belongs to.
065     */
066    @ExcludeFromSizeCalculation
067    protected UserDirectory _userDirectory;
068
069    /**
070     * Enumeration for the user creation origin
071     *
072     */
073    public enum UserCreationOrigin
074    {
075        /** User created by system */
076        SYSTEM,
077        /** User created by an administrator */
078        ADMIN,
079        /** User created by user signup */
080        USER_SIGNUP,
081        /** When user creation is unknown or not available */
082        NOT_AVAILABLE
083    }
084    
085    /**
086     * Construct a new UserPrincipal, associated with the specified login et population id.
087     * 
088     * @param login The login of the principal.
089     * @param populationId The id of the population
090     */
091    public User(String login, String populationId)
092    {
093        this(new UserIdentity(login, populationId));
094    }
095    
096    /**
097     * Construct a new UserPrincipal, associated with the specified identity.
098     * @param identity The identity of this user. Cannot be null
099     */
100    public User(UserIdentity identity)
101    {
102        this(identity, null, null, null, null);
103    }
104
105    /**
106     * Construct a new UserPrincipal, associated with a last name, a first name,
107     * an email and identified by a login.
108     * @param identity The identity of this user. Cannot be null
109     * @param lastName The last name
110     * @param firstName The first name
111     * @param email The email
112     * @param userDirectory The user directory the use rbelongs to. Can be null.
113     */
114    public User(UserIdentity identity, String lastName, String firstName, String email, UserDirectory userDirectory)
115    {
116        this(identity, lastName, firstName, email, userDirectory, null, UserCreationOrigin.NOT_AVAILABLE);
117    }
118    
119    /**
120     * Construct a new UserPrincipal, associated with a last name, a first name,
121     * an email and identified by a login.
122     * @param identity The identity of this user. Cannot be null
123     * @param lastName The last name
124     * @param firstName The first name
125     * @param email The email
126     * @param creationDate the creation date
127     * @param creationOrigin the creation origin
128     * @param userDirectory The user directory the use rbelongs to. Can be null.
129     */
130    public User(UserIdentity identity, String lastName, String firstName, String email, UserDirectory userDirectory, ZonedDateTime creationDate, UserCreationOrigin creationOrigin)
131    {
132        _identity = identity;
133        _lastName = StringUtils.defaultString(lastName);
134        _firstName = StringUtils.defaultString(firstName);
135        _email = StringUtils.defaultString(email);
136        _userDirectory = userDirectory;
137        _creationDate = creationDate;
138        _creationOrigin = creationOrigin;
139    }
140
141    /**
142     * The identity of the user.
143     * 
144     * @return The identity.
145     */
146    public UserIdentity getIdentity()
147    {
148        return _identity;
149    }
150    
151    @Override
152    public String getName()
153    {
154        return UserIdentity.userIdentityToString(_identity);
155    }
156    
157    /**
158     * The last name of the user
159     * @return The last name.
160     */
161    public String getLastName()
162    {
163        return _lastName;
164    }
165    
166    /**
167     * The first name of the user
168     * @return The first name.
169     */
170    public String getFirstName()
171    {
172        return _firstName;
173    }
174    
175    /**
176     * The email of the user represented by this Principal.
177     * 
178     * @return The email.
179     */
180    public String getEmail()
181    {
182        return _email;
183    }
184    
185    /**
186     * The fullname of this user.
187     * @return The full name
188     */
189    public String getFullName()
190    {
191        return _getFullName(true);
192    }
193    
194    /**
195     * The fullname to use to display if sort is needed.
196     * Ensure the sort will be on
197     * @return The sortable name
198     */
199    public String getSortableName()
200    {
201        return _getFullName(false);
202    }
203    
204    /**
205     * The user directory this user belongs to.
206     * @return The user directory
207     */
208    public UserDirectory getUserDirectory()
209    {
210        return _userDirectory;
211    }
212    
213    /**
214     * Get the user's creation date
215     * @return the creation date
216     */
217    public ZonedDateTime getCreationDate()
218    {
219        return _creationDate;
220    }
221    
222    /**
223     * Get the user's creation origin
224     * @return the creation origin
225     */
226    public UserCreationOrigin getCreationOrigin()
227    {
228        return _creationOrigin;
229    }
230    
231    /**
232     * The full name of the user represented by this Principal.
233     * @param firstLast Define the name order if the full name. If true, first name then last name. If false, the contrary.
234     * @return The full name.
235     */
236    protected String _getFullName(boolean firstLast)
237    {
238        Stream<String> stream = firstLast
239                ? Stream.of(getFirstName(), getLastName())
240                : Stream.of(getLastName(), getFirstName());
241        
242        String sortableName = stream.filter(StringUtils::isNotEmpty)
243            .collect(Collectors.joining(" "));
244        
245        return StringUtils.defaultIfEmpty(sortableName, _identity.getLogin());
246    }
247    
248    /**
249     * Return a String representation of this object, which exposes only
250     * information that should be public.
251     * 
252     * @return A string representing the user.
253     */
254    @Override
255    public String toString()
256    {
257        StringBuilder sb = new StringBuilder("Principal[");
258        sb.append(_identity.toString());
259        sb.append(" : ");
260        sb.append(getFullName());
261        sb.append(", ");
262        sb.append(_email);
263        sb.append("]");
264        return sb.toString();
265    }
266
267    /**
268     * Test if two principal are equals.
269     * @return true if the given Object represents the same Principal.
270     */
271    @Override
272    public boolean equals(Object another)
273    {
274        if (another == null || !(another instanceof User))
275        {
276            return false;
277        }
278        
279        User otherUser = (User) another;
280        
281        return _identity != null  && _identity.equals(otherUser.getIdentity());
282    }
283    
284    @Override
285    public int hashCode()
286    {
287        return _identity.hashCode();
288    }
289}