001/*
002 * (C) Copyright 2010-2013 Nuxeo SA (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 *     Olivier Grisel
016 */
017package org.nuxeo.ecm.platform.suggestbox.service.suggesters;
018
019import java.util.ArrayList;
020import java.util.Arrays;
021import java.util.List;
022import java.util.Map;
023
024import org.nuxeo.ecm.core.api.DocumentModel;
025import org.nuxeo.ecm.directory.DirectoryException;
026import org.nuxeo.ecm.platform.suggestbox.service.GroupSuggestion;
027import org.nuxeo.ecm.platform.suggestbox.service.Suggester;
028import org.nuxeo.ecm.platform.suggestbox.service.Suggestion;
029import org.nuxeo.ecm.platform.suggestbox.service.SuggestionContext;
030import org.nuxeo.ecm.platform.suggestbox.service.SuggestionException;
031import org.nuxeo.ecm.platform.suggestbox.service.UserSuggestion;
032import org.nuxeo.ecm.platform.suggestbox.service.descriptors.SuggesterDescriptor;
033import org.nuxeo.ecm.platform.usermanager.UserAdapter;
034import org.nuxeo.ecm.platform.usermanager.UserManager;
035import org.nuxeo.runtime.api.Framework;
036
037/**
038 * Perform a lookup by name query on the UserManager service and suggest to navigate to the top user and / or group
039 * profiles matching that query. If searchFields are provided in the parameters, suggestion for searching document with
040 * reference to the users are also generated.
041 *
042 * @author ogrisel
043 */
044public class UserGroupLookupSuggester implements Suggester {
045
046    protected String userIconURL = "/icons/user.png";
047
048    protected String groupIconURL = "/icons/group.png";
049
050    protected String searchIconURL = "/img/facetedSearch.png";
051
052    protected SuggesterDescriptor descriptor;
053
054    protected List<String> searchFields = new ArrayList<String>();
055
056    protected final String searchLabelPrefix = "label.searchDocumentsByUser_";
057
058    protected int userSuggestionsLimit = 5;
059
060    protected int groupSuggestionsLimit = 5;
061
062    protected String suggesterId = "UserGroupLookupSuggester";
063
064    @Override
065    public List<Suggestion> suggest(String userInput, SuggestionContext context) throws SuggestionException {
066        I18nHelper i18n = I18nHelper.instanceFor(context.messages);
067        UserManager userManager = Framework.getLocalService(UserManager.class);
068        List<Suggestion> suggestions = new ArrayList<Suggestion>();
069        List<Suggestion> searchSuggestions = new ArrayList<Suggestion>();
070        try {
071            int count = 0;
072            for (DocumentModel userDoc : userManager.searchUsers(userInput)) {
073                UserAdapter user = userDoc.getAdapter(UserAdapter.class);
074                // suggest to navigate to the user profile
075                String firstName = user.getFirstName();
076                String userLabel = firstName != null ? firstName : "";
077                String lastName = user.getLastName();
078                userLabel += " ";
079                userLabel += lastName != null ? lastName : "";
080                userLabel = userLabel.trim();
081                if (userLabel.isEmpty()) {
082                    userLabel = user.getName();
083                }
084                suggestions.add(new UserSuggestion(userDoc.getId(), userLabel, userIconURL));
085
086                count++;
087                if (count >= userSuggestionsLimit) {
088                    break;
089                }
090            }
091            count = 0;
092            String groupIdField = userManager.getGroupIdField();
093            String groupLabelField = userManager.getGroupLabelField();
094            for (DocumentModel group : userManager.searchGroups(userInput)) {
095                String label = group.getProperty(groupLabelField).getValue(String.class);
096                if (label == null || label.isEmpty()) {
097                    label = group.getProperty(groupIdField).getValue(String.class);
098                }
099                suggestions.add(new GroupSuggestion(group.getId(), label, groupIconURL));
100                count++;
101                if (count >= groupSuggestionsLimit) {
102                    break;
103                }
104            }
105            suggestions.addAll(searchSuggestions);
106            return suggestions;
107        } catch (DirectoryException e) {
108            throw new SuggestionException(String.format("Suggester '%s' failed to perform query with input '%s'",
109                    descriptor.getName(), userInput), e);
110        }
111    }
112
113    @Override
114    public void initWithParameters(SuggesterDescriptor descriptor) {
115        Map<String, String> params = descriptor.getParameters();
116        String userIconURL = params.get("userIconURL");
117        if (userIconURL != null) {
118            this.userIconURL = userIconURL;
119        }
120        String groupIconURL = params.get("groupIconURL");
121        if (groupIconURL != null) {
122            this.groupIconURL = groupIconURL;
123        }
124        String searchIconURL = params.get("searchIconURL");
125        if (searchIconURL != null) {
126            this.searchIconURL = searchIconURL;
127        }
128        String userSuggestionsLimit = params.get("userSuggestionsLimit");
129        if (userSuggestionsLimit != null) {
130            this.userSuggestionsLimit = Integer.valueOf(userSuggestionsLimit).intValue();
131        }
132        String groupSuggestionsLimit = params.get("groupSuggestionsLimit");
133        if (groupSuggestionsLimit != null) {
134            this.groupSuggestionsLimit = Integer.valueOf(groupSuggestionsLimit).intValue();
135        }
136        String searchFields = params.get("searchFields");
137        if (searchFields != null && !searchFields.isEmpty()) {
138            this.searchFields = Arrays.asList(searchFields.split(", *"));
139        }
140        this.descriptor = descriptor;
141    }
142}