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.BooleanClauseOccur;
18  import com.liferay.portal.kernel.search.BooleanQuery;
19  import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
20  import com.liferay.portal.kernel.search.Document;
21  import com.liferay.portal.kernel.search.DocumentImpl;
22  import com.liferay.portal.kernel.search.Field;
23  import com.liferay.portal.kernel.search.SearchContext;
24  import com.liferay.portal.kernel.search.SearchEngineUtil;
25  import com.liferay.portal.kernel.search.Summary;
26  import com.liferay.portal.kernel.util.GetterUtil;
27  import com.liferay.portal.kernel.util.SetUtil;
28  import com.liferay.portal.kernel.util.UnicodeProperties;
29  import com.liferay.portal.kernel.util.Validator;
30  import com.liferay.portal.model.ContactConstants;
31  import com.liferay.portal.model.Organization;
32  import com.liferay.portal.model.User;
33  import com.liferay.portal.search.BaseIndexer;
34  import com.liferay.portal.service.OrganizationLocalServiceUtil;
35  import com.liferay.portal.service.UserLocalServiceUtil;
36  import com.liferay.portal.util.PortletKeys;
37  import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
38  import com.liferay.portlet.expando.model.ExpandoBridge;
39  import com.liferay.portlet.expando.model.ExpandoColumnConstants;
40  import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
41  import com.liferay.portlet.expando.util.ExpandoBridgeIndexer;
42  import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
43  
44  import java.util.ArrayList;
45  import java.util.LinkedHashMap;
46  import java.util.List;
47  import java.util.Map;
48  import java.util.Set;
49  
50  import javax.portlet.PortletURL;
51  
52  /**
53   * <a href="UserIndexer.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Raymond Augé
56   * @author Zsigmond Rab
57   */
58  public class UserIndexer extends BaseIndexer {
59  
60      public static final String[] CLASS_NAMES = {User.class.getName()};
61  
62      public static final String PORTLET_ID = PortletKeys.ENTERPRISE_ADMIN_USERS;
63  
64      public String[] getClassNames() {
65          return CLASS_NAMES;
66      }
67  
68      public Summary getSummary(
69          Document document, String snippet, PortletURL portletURL) {
70  
71          String firstName = document.get("firstName");
72          String middleName = document.get("middleName");
73          String lastName = document.get("lastName");
74  
75          String title = ContactConstants.getFullName(
76              firstName, middleName, lastName);
77  
78          String content = null;
79  
80          String userId = document.get(Field.USER_ID);
81  
82          portletURL.setParameter("struts_action", "/enterprise_admin/edit_user");
83          portletURL.setParameter("p_u_i_d", userId);
84  
85          return new Summary(title, content, portletURL);
86      }
87  
88      protected void addContextQueryParams(
89              BooleanQuery contextQuery, String key, Object value)
90          throws Exception {
91  
92          if (key.equals("usersOrgs")) {
93              if (value instanceof Long[]) {
94                  Long[] values = (Long[])value;
95  
96                  BooleanQuery usersOrgsQuery =
97                      BooleanQueryFactoryUtil.create();
98  
99                  for (long organizationId : values) {
100                     usersOrgsQuery.addTerm(
101                         "organizationIds", organizationId);
102                     usersOrgsQuery.addTerm(
103                         "ancestorOrganizationIds", organizationId);
104                 }
105 
106                 contextQuery.add(usersOrgsQuery, BooleanClauseOccur.MUST);
107             }
108             else {
109                 contextQuery.addRequiredTerm(
110                     "organizationIds", String.valueOf(value));
111             }
112         }
113         else if (key.equals("usersRoles")) {
114             contextQuery.addRequiredTerm("roleIds", String.valueOf(value));
115         }
116         else if (key.equals("usersUserGroups")) {
117             contextQuery.addRequiredTerm("userGroupIds", String.valueOf(value));
118         }
119     }
120 
121     protected void addSearchQueryParams(
122             BooleanQuery searchQuery, ExpandoBridge expandoBridge,
123             Set<String> attributeNames, String key, Object value,
124             boolean andSearch)
125         throws Exception {
126 
127         if (attributeNames.contains(key)) {
128             UnicodeProperties properties = expandoBridge.getAttributeProperties(
129                 key);
130 
131             if (GetterUtil.getBoolean(
132                     properties.getProperty(ExpandoBridgeIndexer.INDEXABLE))) {
133 
134                 int type = expandoBridge.getAttributeType(key);
135 
136                 if ((type == ExpandoColumnConstants.STRING) &&
137                     (Validator.isNotNull((String)value))) {
138 
139                     if (andSearch) {
140                         searchQuery.addRequiredTerm(key, (String)value, true);
141                     }
142                     else {
143                         searchQuery.addTerm(key, (String)value, true);
144                     }
145                 }
146             }
147         }
148         else if (Validator.isNotNull(key) && Validator.isNotNull(value)) {
149             if (andSearch) {
150                 searchQuery.addRequiredTerm(key, String.valueOf(value));
151             }
152             else {
153                 searchQuery.addTerm(key, String.valueOf(value));
154             }
155         }
156     }
157 
158     protected void doDelete(Object obj) throws Exception {
159         User user = (User)obj;
160 
161         Document document = new DocumentImpl();
162 
163         document.addUID(PORTLET_ID, user.getUserId());
164 
165         SearchEngineUtil.deleteDocument(
166             user.getCompanyId(), document.get(Field.UID));
167     }
168 
169     protected Document doGetDocument(Object obj) throws Exception {
170         User user = (User)obj;
171 
172         long companyId = user.getCompanyId();
173         long userId = user.getUserId();
174         String screenName = user.getScreenName();
175         String emailAddress = user.getEmailAddress();
176         String firstName = user.getFirstName();
177         String middleName = user.getMiddleName();
178         String lastName = user.getLastName();
179         String jobTitle = user.getJobTitle();
180         boolean active = user.isActive();
181         long[] groupIds = user.getGroupIds();
182         long[] organizationIds = user.getOrganizationIds();
183         long[] roleIds = user.getRoleIds();
184         long[] userGroupIds = user.getUserGroupIds();
185 
186         String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
187             User.class.getName(), userId);
188 
189         ExpandoBridge expandoBridge = user.getExpandoBridge();
190 
191         Document document = new DocumentImpl();
192 
193         document.addUID(PORTLET_ID, userId);
194 
195         document.addModifiedDate();
196 
197         document.addKeyword(Field.COMPANY_ID, companyId);
198         document.addKeyword(Field.PORTLET_ID, PORTLET_ID);
199         document.addKeyword(Field.USER_ID, userId);
200 
201         document.addKeyword("screenName", screenName);
202         document.addKeyword("emailAddress", emailAddress);
203         document.addKeyword("firstName", firstName, true);
204         document.addKeyword("middleName", middleName, true);
205         document.addKeyword("lastName", lastName, true);
206         document.addKeyword("jobTitle", jobTitle);
207         document.addKeyword("active", active);
208         document.addKeyword("groupIds", groupIds);
209         document.addKeyword("organizationIds", organizationIds);
210         document.addKeyword(
211             "ancestorOrganizationIds",
212             getAncestorOrganizationIds(userId, organizationIds));
213         document.addKeyword("roleIds", roleIds);
214         document.addKeyword("userGroupIds", userGroupIds);
215 
216         document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);
217 
218         ExpandoBridgeIndexerUtil.addAttributes(document, expandoBridge);
219 
220         return document;
221     }
222 
223     protected void doReindex(Object obj) throws Exception {
224         if (obj instanceof List<?>) {
225             List<User> users = (List<User>)obj;
226 
227             for (User user : users) {
228                 doReindex(user);
229             }
230         }
231         else if (obj instanceof Long) {
232             long userId = (Long)obj;
233 
234             User user = UserLocalServiceUtil.getUserById(userId);
235 
236             doReindex(user);
237         }
238         else if (obj instanceof long[]) {
239             long[] userIds = (long[])obj;
240 
241             for (long userId : userIds) {
242                 User user = UserLocalServiceUtil.getUserById(userId);
243 
244                 doReindex(user);
245             }
246         }
247         else if (obj instanceof User) {
248             User user = (User)obj;
249 
250             if (user.isDefaultUser()) {
251                 return;
252             }
253 
254             Document document = getDocument(user);
255 
256             SearchEngineUtil.updateDocument(
257                 user.getCompanyId(), document.get(Field.UID), document);
258         }
259     }
260 
261     protected void doReindex(String className, long classPK) throws Exception {
262         User user = UserLocalServiceUtil.getUserById(classPK);
263 
264         doReindex(user);
265     }
266 
267     protected void doReindex(String[] ids) throws Exception {
268         long companyId = GetterUtil.getLong(ids[0]);
269 
270         reindexUsers(companyId);
271     }
272 
273     protected long[] getAncestorOrganizationIds(
274             long userId, long[] organizationIds)
275         throws Exception {
276 
277         List<Organization> ancestorOrganizations =
278             new ArrayList<Organization>();
279 
280         for (long organizationId : organizationIds) {
281             Organization organization =
282                 OrganizationLocalServiceUtil.getOrganization(organizationId);
283 
284             ancestorOrganizations.addAll(organization.getAncestors());
285         }
286 
287         long[] ancestorOrganizationIds = new long[ancestorOrganizations.size()];
288 
289         for (int i = 0; i < ancestorOrganizations.size(); i++) {
290             Organization ancestorOrganization = ancestorOrganizations.get(i);
291 
292             ancestorOrganizationIds[i] =
293                 ancestorOrganization.getOrganizationId();
294         }
295 
296         return ancestorOrganizationIds;
297     }
298 
299     protected String getPortletId(SearchContext searchContext) {
300         return PORTLET_ID;
301     }
302 
303     protected void postProcessContextQuery(
304             BooleanQuery contextQuery, SearchContext searchContext)
305         throws Exception {
306 
307         Boolean active = (Boolean)searchContext.getAttribute("active");
308 
309         if (active != null) {
310             contextQuery.addRequiredTerm("active", active);
311         }
312 
313         LinkedHashMap<String, Object> params =
314             (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
315 
316         if (params == null) {
317             return;
318         }
319 
320         for (Map.Entry<String, Object> entry : params.entrySet()) {
321             String key = entry.getKey();
322             Object value = entry.getValue();
323 
324             if (value == null) {
325                 continue;
326             }
327 
328             addContextQueryParams(contextQuery, key, value);
329         }
330     }
331 
332     protected void postProcessSearchQuery(
333             BooleanQuery searchQuery, SearchContext searchContext)
334         throws Exception {
335 
336         Boolean andSearch = (Boolean)searchContext.getAttribute("andSearch");
337 
338         if (andSearch == null) {
339             andSearch = Boolean.TRUE;
340         }
341 
342         String firstName = (String)searchContext.getAttribute("firstName");
343 
344         if (Validator.isNotNull(firstName)) {
345             if (andSearch) {
346                 searchQuery.addRequiredTerm("firstName", firstName, true);
347             }
348             else {
349                 searchQuery.addTerm("firstName", firstName, true);
350             }
351         }
352 
353         String middleName = (String)searchContext.getAttribute("middleName");
354 
355         if (Validator.isNotNull(middleName)) {
356             if (andSearch) {
357                 searchQuery.addRequiredTerm("middleName", middleName, true);
358             }
359             else {
360                 searchQuery.addTerm("middleName", middleName, true);
361             }
362         }
363 
364         String lastName = (String)searchContext.getAttribute("lastName");
365 
366         if (Validator.isNotNull(lastName)) {
367             if (andSearch) {
368                 searchQuery.addRequiredTerm("lastName", lastName, true);
369             }
370             else {
371                 searchQuery.addTerm("lastName", lastName, true);
372             }
373         }
374 
375         String screenName = (String)searchContext.getAttribute("screenName");
376 
377         if (Validator.isNotNull(screenName)) {
378             if (andSearch) {
379                 searchQuery.addRequiredTerm("screenName", screenName, true);
380             }
381             else {
382                 searchQuery.addTerm("screenName", screenName, true);
383             }
384         }
385 
386         String emailAddress = (String)searchContext.getAttribute(
387             "emailAddress");
388 
389         if (Validator.isNotNull(emailAddress)) {
390             if (andSearch) {
391                 searchQuery.addRequiredTerm(
392                     "emailAddress", emailAddress, true);
393             }
394             else {
395                 searchQuery.addTerm("emailAddress", emailAddress, true);
396             }
397         }
398 
399         LinkedHashMap<String, Object> params =
400             (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
401 
402         if (params != null) {
403             ExpandoBridge expandoBridge =
404                 ExpandoBridgeFactoryUtil.getExpandoBridge(
405                     searchContext.getCompanyId(), User.class.getName());
406 
407             Set<String> attributeNames = SetUtil.fromEnumeration(
408                 expandoBridge.getAttributeNames());
409 
410             for (Map.Entry<String, Object> entry : params.entrySet()) {
411                 String key = entry.getKey();
412                 Object value = entry.getValue();
413 
414                 if (key.equals("usersOrgs") || key.equals("usersRoles") ||
415                     key.equals("usersUserGroups") || (value == null)) {
416 
417                     continue;
418                 }
419 
420                 addSearchQueryParams(
421                     searchQuery, expandoBridge, attributeNames, key, value,
422                     andSearch);
423             }
424         }
425     }
426 
427     protected void reindexUsers(long companyId) throws Exception {
428         int count = UserLocalServiceUtil.getCompanyUsersCount(companyId);
429 
430         int pages = count / UserIndexer.DEFAULT_INTERVAL;
431 
432         for (int i = 0; i <= pages; i++) {
433             int start = (i * UserIndexer.DEFAULT_INTERVAL);
434             int end = start + UserIndexer.DEFAULT_INTERVAL;
435 
436             reindexUsers(companyId, start, end);
437         }
438     }
439 
440     protected void reindexUsers(long companyId, int start, int end)
441         throws Exception {
442 
443         List<User> users = UserLocalServiceUtil.getCompanyUsers(
444             companyId, start, end);
445 
446         for (User user : users) {
447             reindex(user);
448         }
449     }
450 
451 }