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