1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.enterpriseadmin.util;
16  
17  import com.liferay.portal.kernel.search.BaseIndexer;
18  import com.liferay.portal.kernel.search.BooleanClauseOccur;
19  import com.liferay.portal.kernel.search.BooleanQuery;
20  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
21  import com.liferay.portal.kernel.search.Document;
22  import com.liferay.portal.kernel.search.DocumentImpl;
23  import com.liferay.portal.kernel.search.Field;
24  import com.liferay.portal.kernel.search.SearchContext;
25  import com.liferay.portal.kernel.search.SearchEngineUtil;
26  import com.liferay.portal.kernel.search.Summary;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.SetUtil;
29  import com.liferay.portal.kernel.util.UnicodeProperties;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.model.Organization;
32  import com.liferay.portal.model.User;
33  import com.liferay.portal.security.auth.FullNameGenerator;
34  import com.liferay.portal.security.auth.FullNameGeneratorFactory;
35  import com.liferay.portal.service.OrganizationLocalServiceUtil;
36  import com.liferay.portal.service.UserLocalServiceUtil;
37  import com.liferay.portal.util.PortletKeys;
38  import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
39  import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
40  import com.liferay.portlet.expando.model.ExpandoBridge;
41  import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
42  import com.liferay.portlet.expando.util.ExpandoBridgeIndexer;
43  import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
44  
45  import java.util.ArrayList;
46  import java.util.Collection;
47  import java.util.HashMap;
48  import java.util.LinkedHashMap;
49  import java.util.List;
50  import java.util.Map;
51  import java.util.Set;
52  
53  import javax.portlet.PortletURL;
54  
55  /**
56   * <a href="UserIndexer.java.html"><b><i>View Source</i></b></a>
57   *
58   * @author Raymond Augé
59   * @author Zsigmond Rab
60   */
61  public class UserIndexer extends BaseIndexer {
62  
63      public static final String[] CLASS_NAMES = {User.class.getName()};
64  
65      public static final String PORTLET_ID = PortletKeys.ENTERPRISE_ADMIN_USERS;
66  
67      public String[] getClassNames() {
68          return CLASS_NAMES;
69      }
70  
71      public Summary getSummary(
72          Document document, String snippet, PortletURL portletURL) {
73  
74          String firstName = document.get("firstName");
75          String middleName = document.get("middleName");
76          String lastName = document.get("lastName");
77  
78          FullNameGenerator fullNameGenerator =
79              FullNameGeneratorFactory.getInstance();
80  
81          String title = fullNameGenerator.getFullName(
82              firstName, middleName, lastName);
83  
84          String content = null;
85  
86          String userId = document.get(Field.USER_ID);
87  
88          portletURL.setParameter("struts_action", "/enterprise_admin/edit_user");
89          portletURL.setParameter("p_u_i_d", userId);
90  
91          return new Summary(title, content, portletURL);
92      }
93  
94      protected void addContextQueryParams(
95              BooleanQuery contextQuery, String key, Object value)
96          throws Exception {
97  
98          if (key.equals("usersOrgs")) {
99              if (value instanceof Long[]) {
100                 Long[] values = (Long[])value;
101 
102                 BooleanQuery usersOrgsQuery =
103                     BooleanQueryFactoryUtil.create();
104 
105                 for (long organizationId : values) {
106                     usersOrgsQuery.addTerm(
107                         "organizationIds", organizationId);
108                     usersOrgsQuery.addTerm(
109                         "ancestorOrganizationIds", organizationId);
110                 }
111 
112                 contextQuery.add(usersOrgsQuery, BooleanClauseOccur.MUST);
113             }
114             else {
115                 contextQuery.addRequiredTerm(
116                     "organizationIds", String.valueOf(value));
117             }
118         }
119         else if (key.equals("usersRoles")) {
120             contextQuery.addRequiredTerm("roleIds", String.valueOf(value));
121         }
122         else if (key.equals("usersTeams")) {
123             contextQuery.addRequiredTerm("teamIds", String.valueOf(value));
124         }
125         else if (key.equals("usersUserGroups")) {
126             contextQuery.addRequiredTerm("userGroupIds", String.valueOf(value));
127         }
128     }
129 
130     protected void addSearchQueryParams(
131             BooleanQuery searchQuery, SearchContext searchContext,
132             ExpandoBridge expandoBridge, Set<String> attributeNames, String key,
133             Object value)
134         throws Exception {
135 
136         if (attributeNames.contains(key)) {
137             UnicodeProperties properties = expandoBridge.getAttributeProperties(
138                 key);
139 
140             if (GetterUtil.getBoolean(
141                     properties.getProperty(ExpandoBridgeIndexer.INDEXABLE))) {
142 
143                 String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
144                     key);
145 
146                 if (Validator.isNotNull((String)value)) {
147                     if (searchContext.isAndSearch()) {
148                         searchQuery.addRequiredTerm(
149                             fieldName, (String)value, true);
150                     }
151                     else {
152                         searchQuery.addTerm(fieldName, (String)value, true);
153                     }
154                 }
155             }
156         }
157         else if (Validator.isNotNull(key) && Validator.isNotNull(value)) {
158             if (searchContext.isAndSearch()) {
159                 searchQuery.addRequiredTerm(key, String.valueOf(value));
160             }
161             else {
162                 searchQuery.addTerm(key, String.valueOf(value));
163             }
164         }
165     }
166 
167     protected void doDelete(Object obj) throws Exception {
168         User user = (User)obj;
169 
170         Document document = new DocumentImpl();
171 
172         document.addUID(PORTLET_ID, user.getUserId());
173 
174         SearchEngineUtil.deleteDocument(
175             user.getCompanyId(), document.get(Field.UID));
176     }
177 
178     protected Document doGetDocument(Object obj) throws Exception {
179         User user = (User)obj;
180 
181         long companyId = user.getCompanyId();
182         long userId = user.getUserId();
183         String screenName = user.getScreenName();
184         String emailAddress = user.getEmailAddress();
185         String firstName = user.getFirstName();
186         String middleName = user.getMiddleName();
187         String lastName = user.getLastName();
188         String jobTitle = user.getJobTitle();
189         boolean active = user.isActive();
190         long[] groupIds = user.getGroupIds();
191         long[] organizationIds = user.getOrganizationIds();
192         long[] roleIds = user.getRoleIds();
193         long[] teamIds = user.getTeamIds();
194         long[] userGroupIds = user.getUserGroupIds();
195 
196         long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
197             User.class.getName(), userId);
198         String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
199             User.class.getName(), userId);
200 
201         ExpandoBridge expandoBridge = user.getExpandoBridge();
202 
203         Document document = new DocumentImpl();
204 
205         document.addUID(PORTLET_ID, userId);
206 
207         document.addModifiedDate();
208 
209         document.addKeyword(Field.COMPANY_ID, companyId);
210         document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
211         document.addKeyword(Field.USER_ID, userId);
212 
213         document.addKeyword("screenName", screenName);
214         document.addKeyword("emailAddress", emailAddress);
215         document.addKeyword("firstName", firstName, true);
216         document.addKeyword("middleName", middleName, true);
217         document.addKeyword("lastName", lastName, true);
218         document.addKeyword("jobTitle", jobTitle);
219         document.addKeyword("active", active);
220         document.addKeyword("groupIds", groupIds);
221         document.addKeyword("organizationIds", organizationIds);
222         document.addKeyword(
223             "ancestorOrganizationIds",
224             getAncestorOrganizationIds(userId, organizationIds));
225         document.addKeyword("roleIds", roleIds);
226         document.addKeyword("teamIds", teamIds);
227         document.addKeyword("userGroupIds", userGroupIds);
228 
229         document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
230         document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
231 
232         document.addKeyword(Field.ENTRY_CLASS_NAME, User.class.getName());
233         document.addKeyword(Field.ENTRY_CLASS_PK, userId);
234 
235         ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
236 
237         return document;
238     }
239 
240     protected void doReindex(Object obj) throws Exception {
241         if (obj instanceof List<?>) {
242             List<User> users = (List<User>)obj;
243 
244             for (User user : users) {
245                 doReindex(user);
246             }
247         }
248         else if (obj instanceof Long) {
249             long userId = (Long)obj;
250 
251             User user = UserLocalServiceUtil.getUserById(userId);
252 
253             doReindex(user);
254         }
255         else if (obj instanceof long[]) {
256             long[] userIds = (long[])obj;
257 
258             Map<Long, Collection<Document>> documentsMap =
259                 new HashMap<Long, Collection<Document>>();
260 
261             for (long userId : userIds) {
262                 User user = UserLocalServiceUtil.getUserById(userId);
263 
264                 if (user.isDefaultUser()) {
265                     continue;
266                 }
267 
268                 Document document = getDocument(user);
269 
270                 long companyId = user.getCompanyId();
271 
272                 Collection<Document> documents = documentsMap.get(companyId);
273 
274                 if (documents == null) {
275                     documents = new ArrayList<Document>();
276 
277                     documentsMap.put(companyId, documents);
278                 }
279 
280                 documents.add(document);
281             }
282 
283             for (Map.Entry<Long, Collection<Document>> entry :
284                     documentsMap.entrySet()) {
285 
286                 long companyId = entry.getKey();
287                 Collection<Document> documents = entry.getValue();
288 
289                 SearchEngineUtil.updateDocuments(companyId, documents);
290             }
291         }
292         else if (obj instanceof User) {
293             User user = (User)obj;
294 
295             if (user.isDefaultUser()) {
296                 return;
297             }
298 
299             Document document = getDocument(user);
300 
301             SearchEngineUtil.updateDocument(user.getCompanyId(), document);
302         }
303     }
304 
305     protected void doReindex(String className, long classPK) throws Exception {
306         User user = UserLocalServiceUtil.getUserById(classPK);
307 
308         doReindex(user);
309     }
310 
311     protected void doReindex(String[] ids) throws Exception {
312         long companyId = GetterUtil.getLong(ids[0]);
313 
314         reindexUsers(companyId);
315     }
316 
317     protected long[] getAncestorOrganizationIds(
318             long userId, long[] organizationIds)
319         throws Exception {
320 
321         List<Organization> ancestorOrganizations =
322             new ArrayList<Organization>();
323 
324         for (long organizationId : organizationIds) {
325             Organization organization =
326                 OrganizationLocalServiceUtil.getOrganization(organizationId);
327 
328             ancestorOrganizations.addAll(organization.getAncestors());
329         }
330 
331         long[] ancestorOrganizationIds = new long[ancestorOrganizations.size()];
332 
333         for (int i = 0; i < ancestorOrganizations.size(); i++) {
334             Organization ancestorOrganization = ancestorOrganizations.get(i);
335 
336             ancestorOrganizationIds[i] =
337                 ancestorOrganization.getOrganizationId();
338         }
339 
340         return ancestorOrganizationIds;
341     }
342 
343     protected String getPortletId(SearchContext searchContext) {
344         return PORTLET_ID;
345     }
346 
347     protected void postProcessContextQuery(
348             BooleanQuery contextQuery, SearchContext searchContext)
349         throws Exception {
350 
351         Boolean active = (Boolean)searchContext.getAttribute("active");
352 
353         if (active != null) {
354             contextQuery.addRequiredTerm("active", active);
355         }
356 
357         LinkedHashMap<String, Object> params =
358             (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
359 
360         if (params == null) {
361             return;
362         }
363 
364         for (Map.Entry<String, Object> entry : params.entrySet()) {
365             String key = entry.getKey();
366             Object value = entry.getValue();
367 
368             if (value == null) {
369                 continue;
370             }
371 
372             addContextQueryParams(contextQuery, key, value);
373         }
374     }
375 
376     protected void postProcessSearchQuery(
377             BooleanQuery searchQuery, SearchContext searchContext)
378         throws Exception {
379 
380         String emailAddress = (String)searchContext.getAttribute(
381             "emailAddress");
382 
383         if (Validator.isNotNull(emailAddress)) {
384             if (searchContext.isAndSearch()) {
385                 searchQuery.addRequiredTerm(
386                     "emailAddress", emailAddress, true);
387             }
388             else {
389                 searchQuery.addTerm("emailAddress", emailAddress, true);
390             }
391         }
392 
393         String firstName = (String)searchContext.getAttribute("firstName");
394 
395         if (Validator.isNotNull(firstName)) {
396             if (searchContext.isAndSearch()) {
397                 searchQuery.addRequiredTerm("firstName", firstName, true);
398             }
399             else {
400                 searchQuery.addTerm("firstName", firstName, true);
401             }
402         }
403 
404         String lastName = (String)searchContext.getAttribute("lastName");
405 
406         if (Validator.isNotNull(lastName)) {
407             if (searchContext.isAndSearch()) {
408                 searchQuery.addRequiredTerm("lastName", lastName, true);
409             }
410             else {
411                 searchQuery.addTerm("lastName", lastName, true);
412             }
413         }
414 
415         String middleName = (String)searchContext.getAttribute("middleName");
416 
417         if (Validator.isNotNull(middleName)) {
418             if (searchContext.isAndSearch()) {
419                 searchQuery.addRequiredTerm("middleName", middleName, true);
420             }
421             else {
422                 searchQuery.addTerm("middleName", middleName, true);
423             }
424         }
425 
426         String screenName = (String)searchContext.getAttribute("screenName");
427 
428         if (Validator.isNotNull(screenName)) {
429             if (searchContext.isAndSearch()) {
430                 searchQuery.addRequiredTerm("screenName", screenName, true);
431             }
432             else {
433                 searchQuery.addTerm("screenName", screenName, true);
434             }
435         }
436 
437         LinkedHashMap<String, Object> params =
438             (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
439 
440         if (params != null) {
441             ExpandoBridge expandoBridge =
442                 ExpandoBridgeFactoryUtil.getExpandoBridge(
443                     searchContext.getCompanyId(), User.class.getName());
444 
445             Set<String> attributeNames = SetUtil.fromEnumeration(
446                 expandoBridge.getAttributeNames());
447 
448             for (Map.Entry<String, Object> entry : params.entrySet()) {
449                 String key = entry.getKey();
450                 Object value = entry.getValue();
451 
452                 if (key.equals("usersOrgs") || key.equals("usersRoles") ||
453                     key.equals("usersTeams") || key.equals("usersUserGroups") ||
454                     (value == null)) {
455 
456                     continue;
457                 }
458 
459                 addSearchQueryParams(
460                     searchQuery, searchContext, expandoBridge, attributeNames,
461                     key, value);
462             }
463         }
464     }
465 
466     protected void reindexUsers(long companyId) throws Exception {
467         int count = UserLocalServiceUtil.getCompanyUsersCount(companyId);
468 
469         int pages = count / UserIndexer.DEFAULT_INTERVAL;
470 
471         for (int i = 0; i <= pages; i++) {
472             int start = (i * UserIndexer.DEFAULT_INTERVAL);
473             int end = start + UserIndexer.DEFAULT_INTERVAL;
474 
475             reindexUsers(companyId, start, end);
476         }
477     }
478 
479     protected void reindexUsers(long companyId, int start, int end)
480         throws Exception {
481 
482         List<User> users = UserLocalServiceUtil.getCompanyUsers(
483             companyId, start, end);
484 
485         if (users.isEmpty()) {
486             return;
487         }
488 
489         Collection<Document> documents = new ArrayList<Document>();
490 
491         for (User user : users) {
492             if (user.isDefaultUser()) {
493                 continue;
494             }
495 
496             Document document = getDocument(user);
497 
498             documents.add(document);
499         }
500 
501         SearchEngineUtil.updateDocuments(companyId, documents);
502     }
503 
504 }