001/*
002 * (C) Copyright 2007-20015 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 *
018 */
019
020package org.nuxeo.ecm.platform.ui.web.tag.fn;
021
022import org.apache.commons.logging.Log;
023import org.apache.commons.logging.LogFactory;
024import org.nuxeo.ecm.core.api.DataModel;
025import org.nuxeo.ecm.core.api.DocumentModel;
026import org.nuxeo.ecm.core.api.NuxeoPrincipal;
027import org.nuxeo.ecm.core.cache.Cache;
028import org.nuxeo.ecm.core.cache.CacheService;
029import org.nuxeo.ecm.directory.Session;
030import org.nuxeo.ecm.directory.api.DirectoryService;
031import org.nuxeo.ecm.platform.usermanager.UserConfig;
032import org.nuxeo.ecm.platform.usermanager.UserManager;
033import org.nuxeo.runtime.api.Framework;
034import org.nuxeo.runtime.services.event.Event;
035import org.nuxeo.runtime.services.event.EventListener;
036import org.nuxeo.runtime.services.event.EventService;
037
038/**
039 * Helper class to encapsulate userName => DisplayName resolution. Does direct access to the underlying directories to
040 * avoid performance issues.
041 *
042 * @author tiry
043 * @since 7.2
044 */
045public class UserNameResolverHelper implements EventListener {
046
047    protected static final Log log = LogFactory.getLog(UserNameResolverHelper.class);
048
049    public static final String USERNAMECACHE = "userDisplayName";
050
051    protected volatile Cache cache;
052
053    public String getUserFullName(String login) {
054
055        String displayName = null;
056
057        Cache cache = getCache();
058        if (cache != null) {
059            displayName = (String) cache.get(login);
060        }
061
062        if (displayName == null) {
063            displayName = computeUserFullName(login);
064            if (cache != null) {
065                cache.put(login, displayName);
066            }
067        }
068
069        if (displayName == null) {
070            displayName = login;
071        }
072        return displayName;
073    }
074
075    protected Cache getCache() {
076        Cache result = cache;
077        if (result == null) {
078            synchronized (this) {
079                result = cache;
080                if (result == null) {
081                    CacheService cs = Framework.getService(CacheService.class);
082                    if (cs != null) {
083                        result = cs.getCache(USERNAMECACHE);
084                        if (result != null) {
085                            EventService es = Framework.getService(EventService.class);
086                            es.addListener("usermanager", this);
087                        }
088                        cache = result;
089                    }
090                }
091            }
092        }
093        return result;
094    }
095
096    protected String computeUserFullName(String login) {
097
098        UserManager um = Framework.getService(UserManager.class);
099        String dname = um.getUserDirectoryName();
100
101        try (Session dirSession = Framework.getService(DirectoryService.class).open(dname)) {
102            DocumentModel entry = dirSession.getEntry(login, false);
103            if (entry == null) {
104                // virtual user ?
105                NuxeoPrincipal principal = um.getPrincipal(login);
106                if (principal != null) {
107                    return computeUserFullName(principal);
108                } else {
109                    return login;
110                }
111            } else {
112                DataModel model = entry.getDataModel(um.getUserSchemaName());
113                return computeUserFullName(model);
114            }
115        }
116    }
117
118    protected String computeUserFullName(DataModel model) {
119        String first = (String) model.getData(UserConfig.DEFAULT.firstNameKey);
120        String last = (String) model.getData(UserConfig.DEFAULT.lastNameKey);
121        String username = (String) model.getData(UserConfig.DEFAULT.nameKey);
122        return Functions.userDisplayName(username, first, last);
123    }
124
125    protected String computeUserFullName(NuxeoPrincipal principal) {
126        String first = principal.getFirstName();
127        String last = principal.getLastName();
128        return Functions.userDisplayName(principal.getName(), first, last);
129    }
130
131    @Override
132    public boolean aboutToHandleEvent(Event arg0) {
133        return true;
134    }
135
136    @Override
137    public void handleEvent(Event event) {
138        if ("user_changed".equals(event.getId())) {
139            String userName = (String) event.getData();
140            Cache cache = getCache();
141            if (cache != null) {
142                cache.invalidate(userName);
143            }
144        }
145    }
146
147}