001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.enterpriseadmin.util;
016    
017    import com.liferay.portal.kernel.search.BooleanClauseOccur;
018    import com.liferay.portal.kernel.search.BooleanQuery;
019    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
020    import com.liferay.portal.kernel.search.Document;
021    import com.liferay.portal.kernel.search.DocumentImpl;
022    import com.liferay.portal.kernel.search.ExpandoIndexer;
023    import com.liferay.portal.kernel.search.Field;
024    import com.liferay.portal.kernel.search.SearchContext;
025    import com.liferay.portal.kernel.search.SearchEngineUtil;
026    import com.liferay.portal.kernel.search.Summary;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.SetUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.model.Organization;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.security.auth.FullNameGenerator;
033    import com.liferay.portal.security.auth.FullNameGeneratorFactory;
034    import com.liferay.portal.service.OrganizationLocalServiceUtil;
035    import com.liferay.portal.service.UserLocalServiceUtil;
036    import com.liferay.portal.util.PortletKeys;
037    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
038    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
039    import com.liferay.portlet.expando.model.ExpandoBridge;
040    import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
041    import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
042    
043    import java.util.ArrayList;
044    import java.util.Collection;
045    import java.util.HashMap;
046    import java.util.LinkedHashMap;
047    import java.util.List;
048    import java.util.Map;
049    import java.util.Set;
050    
051    import javax.portlet.PortletURL;
052    
053    /**
054     * @author Raymond Augé
055     * @author Zsigmond Rab
056     */
057    public class UserIndexer extends ExpandoIndexer {
058    
059            public static final String[] CLASS_NAMES = {User.class.getName()};
060    
061            public static final String PORTLET_ID = PortletKeys.ENTERPRISE_ADMIN_USERS;
062    
063            public String[] getClassNames() {
064                    return CLASS_NAMES;
065            }
066    
067            public Summary getSummary(
068                    Document document, String snippet, PortletURL portletURL) {
069    
070                    String firstName = document.get("firstName");
071                    String middleName = document.get("middleName");
072                    String lastName = document.get("lastName");
073    
074                    FullNameGenerator fullNameGenerator =
075                            FullNameGeneratorFactory.getInstance();
076    
077                    String title = fullNameGenerator.getFullName(
078                            firstName, middleName, lastName);
079    
080                    String content = null;
081    
082                    String userId = document.get(Field.USER_ID);
083    
084                    portletURL.setParameter("struts_action", "/enterprise_admin/edit_user");
085                    portletURL.setParameter("p_u_i_d", userId);
086    
087                    return new Summary(title, content, portletURL);
088            }
089    
090            protected void addContextQueryParams(
091                            BooleanQuery contextQuery, String key, Object value)
092                    throws Exception {
093    
094                    if (key.equals("usersOrgs")) {
095                            if (value instanceof Long[]) {
096                                    Long[] values = (Long[])value;
097    
098                                    BooleanQuery usersOrgsQuery =
099                                            BooleanQueryFactoryUtil.create();
100    
101                                    for (long organizationId : values) {
102                                            usersOrgsQuery.addTerm(
103                                                    "organizationIds", organizationId);
104                                            usersOrgsQuery.addTerm(
105                                                    "ancestorOrganizationIds", organizationId);
106                                    }
107    
108                                    contextQuery.add(usersOrgsQuery, BooleanClauseOccur.MUST);
109                            }
110                            else {
111                                    contextQuery.addRequiredTerm(
112                                            "organizationIds", String.valueOf(value));
113                            }
114                    }
115                    else if (key.equals("usersRoles")) {
116                            contextQuery.addRequiredTerm("roleIds", String.valueOf(value));
117                    }
118                    else if (key.equals("usersTeams")) {
119                            contextQuery.addRequiredTerm("teamIds", String.valueOf(value));
120                    }
121                    else if (key.equals("usersUserGroups")) {
122                            contextQuery.addRequiredTerm("userGroupIds", String.valueOf(value));
123                    }
124            }
125    
126            protected void doDelete(Object obj) throws Exception {
127                    User user = (User)obj;
128    
129                    Document document = new DocumentImpl();
130    
131                    document.addUID(PORTLET_ID, user.getUserId());
132    
133                    SearchEngineUtil.deleteDocument(
134                            user.getCompanyId(), document.get(Field.UID));
135            }
136    
137            protected Document doGetDocument(Object obj) throws Exception {
138                    User user = (User)obj;
139    
140                    long companyId = user.getCompanyId();
141                    long userId = user.getUserId();
142                    String screenName = user.getScreenName();
143                    String emailAddress = user.getEmailAddress();
144                    String firstName = user.getFirstName();
145                    String middleName = user.getMiddleName();
146                    String lastName = user.getLastName();
147                    String jobTitle = user.getJobTitle();
148                    boolean active = user.isActive();
149                    long[] groupIds = user.getGroupIds();
150                    long[] organizationIds = user.getOrganizationIds();
151                    long[] roleIds = user.getRoleIds();
152                    long[] teamIds = user.getTeamIds();
153                    long[] userGroupIds = user.getUserGroupIds();
154    
155                    long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
156                            User.class.getName(), userId);
157                    String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
158                            User.class.getName(), userId);
159    
160                    ExpandoBridge expandoBridge = user.getExpandoBridge();
161    
162                    Document document = new DocumentImpl();
163    
164                    document.addUID(PORTLET_ID, userId);
165    
166                    document.addModifiedDate();
167    
168                    document.addKeyword(Field.COMPANY_ID, companyId);
169                    document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
170                    document.addKeyword(Field.USER_ID, userId);
171    
172                    document.addKeyword("screenName", screenName);
173                    document.addKeyword("emailAddress", emailAddress);
174                    document.addKeyword("firstName", firstName, true);
175                    document.addKeyword("middleName", middleName, true);
176                    document.addKeyword("lastName", lastName, true);
177                    document.addKeyword("jobTitle", jobTitle);
178                    document.addKeyword("active", active);
179                    document.addKeyword("groupIds", groupIds);
180                    document.addKeyword("organizationIds", organizationIds);
181                    document.addKeyword(
182                            "ancestorOrganizationIds",
183                            getAncestorOrganizationIds(userId, organizationIds));
184                    document.addKeyword("roleIds", roleIds);
185                    document.addKeyword("teamIds", teamIds);
186                    document.addKeyword("userGroupIds", userGroupIds);
187    
188                    document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
189                    document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
190    
191                    document.addKeyword(Field.ENTRY_CLASS_NAME, User.class.getName());
192                    document.addKeyword(Field.ENTRY_CLASS_PK, userId);
193    
194                    ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
195    
196                    return document;
197            }
198    
199            protected void doReindex(Object obj) throws Exception {
200                    if (obj instanceof List<?>) {
201                            List<User> users = (List<User>)obj;
202    
203                            for (User user : users) {
204                                    doReindex(user);
205                            }
206                    }
207                    else if (obj instanceof Long) {
208                            long userId = (Long)obj;
209    
210                            User user = UserLocalServiceUtil.getUserById(userId);
211    
212                            doReindex(user);
213                    }
214                    else if (obj instanceof long[]) {
215                            long[] userIds = (long[])obj;
216    
217                            Map<Long, Collection<Document>> documentsMap =
218                                    new HashMap<Long, Collection<Document>>();
219    
220                            for (long userId : userIds) {
221                                    User user = UserLocalServiceUtil.getUserById(userId);
222    
223                                    if (user.isDefaultUser()) {
224                                            continue;
225                                    }
226    
227                                    Document document = getDocument(user);
228    
229                                    long companyId = user.getCompanyId();
230    
231                                    Collection<Document> documents = documentsMap.get(companyId);
232    
233                                    if (documents == null) {
234                                            documents = new ArrayList<Document>();
235    
236                                            documentsMap.put(companyId, documents);
237                                    }
238    
239                                    documents.add(document);
240                            }
241    
242                            for (Map.Entry<Long, Collection<Document>> entry :
243                                            documentsMap.entrySet()) {
244    
245                                    long companyId = entry.getKey();
246                                    Collection<Document> documents = entry.getValue();
247    
248                                    SearchEngineUtil.updateDocuments(companyId, documents);
249                            }
250                    }
251                    else if (obj instanceof User) {
252                            User user = (User)obj;
253    
254                            if (user.isDefaultUser()) {
255                                    return;
256                            }
257    
258                            Document document = getDocument(user);
259    
260                            SearchEngineUtil.updateDocument(user.getCompanyId(), document);
261                    }
262            }
263    
264            protected void doReindex(String className, long classPK) throws Exception {
265                    User user = UserLocalServiceUtil.getUserById(classPK);
266    
267                    doReindex(user);
268            }
269    
270            protected void doReindex(String[] ids) throws Exception {
271                    long companyId = GetterUtil.getLong(ids[0]);
272    
273                    reindexUsers(companyId);
274            }
275    
276            protected long[] getAncestorOrganizationIds(
277                            long userId, long[] organizationIds)
278                    throws Exception {
279    
280                    List<Organization> ancestorOrganizations =
281                            new ArrayList<Organization>();
282    
283                    for (long organizationId : organizationIds) {
284                            Organization organization =
285                                    OrganizationLocalServiceUtil.getOrganization(organizationId);
286    
287                            ancestorOrganizations.addAll(organization.getAncestors());
288                    }
289    
290                    long[] ancestorOrganizationIds = new long[ancestorOrganizations.size()];
291    
292                    for (int i = 0; i < ancestorOrganizations.size(); i++) {
293                            Organization ancestorOrganization = ancestorOrganizations.get(i);
294    
295                            ancestorOrganizationIds[i] =
296                                    ancestorOrganization.getOrganizationId();
297                    }
298    
299                    return ancestorOrganizationIds;
300            }
301    
302            protected String getPortletId(SearchContext searchContext) {
303                    return PORTLET_ID;
304            }
305    
306            protected void postProcessContextQuery(
307                            BooleanQuery contextQuery, SearchContext searchContext)
308                    throws Exception {
309    
310                    Boolean active = (Boolean)searchContext.getAttribute("active");
311    
312                    if (active != null) {
313                            contextQuery.addRequiredTerm("active", active);
314                    }
315    
316                    LinkedHashMap<String, Object> params =
317                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
318    
319                    if (params == null) {
320                            return;
321                    }
322    
323                    for (Map.Entry<String, Object> entry : params.entrySet()) {
324                            String key = entry.getKey();
325                            Object value = entry.getValue();
326    
327                            if (value == null) {
328                                    continue;
329                            }
330    
331                            addContextQueryParams(contextQuery, key, value);
332                    }
333            }
334    
335            protected void postProcessSearchQuery(
336                            BooleanQuery searchQuery, SearchContext searchContext)
337                    throws Exception {
338    
339                    String emailAddress = (String)searchContext.getAttribute(
340                            "emailAddress");
341    
342                    if (Validator.isNotNull(emailAddress)) {
343                            if (searchContext.isAndSearch()) {
344                                    searchQuery.addRequiredTerm(
345                                            "emailAddress", emailAddress, true);
346                            }
347                            else {
348                                    searchQuery.addTerm("emailAddress", emailAddress, true);
349                            }
350                    }
351    
352                    String firstName = (String)searchContext.getAttribute("firstName");
353    
354                    if (Validator.isNotNull(firstName)) {
355                            if (searchContext.isAndSearch()) {
356                                    searchQuery.addRequiredTerm("firstName", firstName, true);
357                            }
358                            else {
359                                    searchQuery.addTerm("firstName", firstName, true);
360                            }
361                    }
362    
363                    String lastName = (String)searchContext.getAttribute("lastName");
364    
365                    if (Validator.isNotNull(lastName)) {
366                            if (searchContext.isAndSearch()) {
367                                    searchQuery.addRequiredTerm("lastName", lastName, true);
368                            }
369                            else {
370                                    searchQuery.addTerm("lastName", lastName, true);
371                            }
372                    }
373    
374                    String middleName = (String)searchContext.getAttribute("middleName");
375    
376                    if (Validator.isNotNull(middleName)) {
377                            if (searchContext.isAndSearch()) {
378                                    searchQuery.addRequiredTerm("middleName", middleName, true);
379                            }
380                            else {
381                                    searchQuery.addTerm("middleName", middleName, true);
382                            }
383                    }
384    
385                    String screenName = (String)searchContext.getAttribute("screenName");
386    
387                    if (Validator.isNotNull(screenName)) {
388                            if (searchContext.isAndSearch()) {
389                                    searchQuery.addRequiredTerm("screenName", screenName, true);
390                            }
391                            else {
392                                    searchQuery.addTerm("screenName", screenName, true);
393                            }
394                    }
395    
396                    LinkedHashMap<String, Object> params =
397                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
398    
399                    if (params != null) {
400                            ExpandoBridge expandoBridge =
401                                    ExpandoBridgeFactoryUtil.getExpandoBridge(
402                                            searchContext.getCompanyId(), User.class.getName());
403    
404                            Set<String> attributeNames = SetUtil.fromEnumeration(
405                                    expandoBridge.getAttributeNames());
406    
407                            for (Map.Entry<String, Object> entry : params.entrySet()) {
408                                    String key = entry.getKey();
409                                    Object value = entry.getValue();
410    
411                                    if (key.equals("usersOrgs") || key.equals("usersRoles") ||
412                                            key.equals("usersTeams") || key.equals("usersUserGroups") ||
413                                            (value == null)) {
414    
415                                            continue;
416                                    }
417    
418                                    addSearchQueryParams(
419                                            searchQuery, searchContext, expandoBridge, attributeNames,
420                                            key, value);
421                            }
422                    }
423            }
424    
425            protected void reindexUsers(long companyId) throws Exception {
426                    int count = UserLocalServiceUtil.getCompanyUsersCount(companyId);
427    
428                    int pages = count / UserIndexer.DEFAULT_INTERVAL;
429    
430                    for (int i = 0; i <= pages; i++) {
431                            int start = (i * UserIndexer.DEFAULT_INTERVAL);
432                            int end = start + UserIndexer.DEFAULT_INTERVAL;
433    
434                            reindexUsers(companyId, start, end);
435                    }
436            }
437    
438            protected void reindexUsers(long companyId, int start, int end)
439                    throws Exception {
440    
441                    List<User> users = UserLocalServiceUtil.getCompanyUsers(
442                            companyId, start, end);
443    
444                    if (users.isEmpty()) {
445                            return;
446                    }
447    
448                    Collection<Document> documents = new ArrayList<Document>();
449    
450                    for (User user : users) {
451                            if (user.isDefaultUser()) {
452                                    continue;
453                            }
454    
455                            Document document = getDocument(user);
456    
457                            documents.add(document);
458                    }
459    
460                    SearchEngineUtil.updateDocuments(companyId, documents);
461            }
462    
463    }