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