001/*
002 * (C) Copyright 2007-2016 Nuxeo SA (http://nuxeo.com/) and others.
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 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019package org.nuxeo.ecm.platform.ui.web.tag.fn;
020
021import org.apache.commons.logging.Log;
022import org.apache.commons.logging.LogFactory;
023import org.nuxeo.ecm.core.api.DocumentModel;
024import org.nuxeo.ecm.core.api.NuxeoPrincipal;
025import org.nuxeo.ecm.core.cache.Cache;
026import org.nuxeo.ecm.core.cache.CacheService;
027import org.nuxeo.ecm.directory.Session;
028import org.nuxeo.ecm.directory.api.DirectoryService;
029import org.nuxeo.ecm.platform.usermanager.UserConfig;
030import org.nuxeo.ecm.platform.usermanager.UserManager;
031import org.nuxeo.runtime.api.Framework;
032import org.nuxeo.runtime.services.event.Event;
033import org.nuxeo.runtime.services.event.EventListener;
034import org.nuxeo.runtime.services.event.EventService;
035
036/**
037 * Helper class to encapsulate userName => DisplayName resolution. Does direct access to the underlying directories to
038 * avoid performance issues.
039 *
040 * @author tiry
041 * @since 7.2
042 */
043public class UserNameResolverHelper implements EventListener {
044
045    protected static final Log log = LogFactory.getLog(UserNameResolverHelper.class);
046
047    public static final String USERNAMECACHE = "userDisplayName";
048
049    protected volatile Cache cache;
050
051    public String getUserFullName(String login) {
052
053        String displayName = null;
054
055        Cache cache = getCache();
056        if (cache != null) {
057            displayName = (String) cache.get(login);
058        }
059
060        if (displayName == null) {
061            displayName = computeUserFullName(login);
062            if (cache != null) {
063                cache.put(login, displayName);
064            }
065        }
066
067        if (displayName == null) {
068            displayName = login;
069        }
070        return displayName;
071    }
072
073    protected Cache getCache() {
074        Cache result = cache;
075        if (result == null) {
076            synchronized (this) {
077                result = cache;
078                if (result == null) {
079                    CacheService cs = Framework.getService(CacheService.class);
080                    if (cs != null) {
081                        result = cs.getCache(USERNAMECACHE);
082                        if (result != null) {
083                            EventService es = Framework.getService(EventService.class);
084                            es.addListener("usermanager", this);
085                        }
086                        cache = result;
087                    }
088                }
089            }
090        }
091        return result;
092    }
093
094    protected String computeUserFullName(String login) {
095
096        UserManager um = Framework.getService(UserManager.class);
097        String dname = um.getUserDirectoryName();
098
099        try (Session dirSession = Framework.getService(DirectoryService.class).open(dname)) {
100            DocumentModel entry = dirSession.getEntry(login, false);
101            if (entry == null) {
102                // virtual user ?
103                NuxeoPrincipal principal = um.getPrincipal(login);
104                if (principal != null) {
105                    return computeUserFullName(principal);
106                } else {
107                    return login;
108                }
109            } else {
110                return computeUserFullName(entry, um.getUserSchemaName());
111            }
112        }
113    }
114
115    protected String computeUserFullName(DocumentModel entry, String schema) {
116        String first = (String) entry.getProperty(schema, UserConfig.DEFAULT.firstNameKey);
117        String last = (String) entry.getProperty(schema, UserConfig.DEFAULT.lastNameKey);
118        String username = (String) entry.getProperty(schema, UserConfig.DEFAULT.nameKey);
119        return Functions.userDisplayName(username, first, last);
120    }
121
122    protected String computeUserFullName(NuxeoPrincipal principal) {
123        String first = principal.getFirstName();
124        String last = principal.getLastName();
125        return Functions.userDisplayName(principal.getName(), first, last);
126    }
127
128    @Override
129    public void handleEvent(Event event) {
130        if ("user_changed".equals(event.getId())) {
131            String userName = (String) event.getData();
132            Cache cache = getCache();
133            if (cache != null) {
134                cache.invalidate(userName);
135            }
136        }
137    }
138
139}