001    /**
002     * Copyright (c) 2000-2012 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.usersadmin.util;
016    
017    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
019    import com.liferay.portal.kernel.dao.orm.Projection;
020    import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
021    import com.liferay.portal.kernel.dao.orm.ProjectionList;
022    import com.liferay.portal.kernel.dao.orm.Property;
023    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
024    import com.liferay.portal.kernel.search.BaseIndexer;
025    import com.liferay.portal.kernel.search.BooleanQuery;
026    import com.liferay.portal.kernel.search.Document;
027    import com.liferay.portal.kernel.search.Field;
028    import com.liferay.portal.kernel.search.SearchContext;
029    import com.liferay.portal.kernel.search.SearchEngineUtil;
030    import com.liferay.portal.kernel.search.Summary;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.workflow.WorkflowConstants;
034    import com.liferay.portal.model.Contact;
035    import com.liferay.portal.model.User;
036    import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
037    import com.liferay.portal.service.ContactLocalServiceUtil;
038    import com.liferay.portal.service.UserLocalServiceUtil;
039    import com.liferay.portal.util.PortletKeys;
040    
041    import java.util.ArrayList;
042    import java.util.Collection;
043    import java.util.LinkedHashMap;
044    import java.util.List;
045    import java.util.Locale;
046    
047    import javax.portlet.PortletURL;
048    
049    /**
050     * @author Raymond Augé
051     * @author Zsigmond Rab
052     * @author Hugo Huijser
053     */
054    public class ContactIndexer extends BaseIndexer {
055    
056            public static final String[] CLASS_NAMES = {Contact.class.getName()};
057    
058            public static final String PORTLET_ID = PortletKeys.USERS_ADMIN;
059    
060            public ContactIndexer() {
061                    setStagingAware(false);
062            }
063    
064            public String[] getClassNames() {
065                    return CLASS_NAMES;
066            }
067    
068            public String getPortletId() {
069                    return PORTLET_ID;
070            }
071    
072            @Override
073            public void postProcessSearchQuery(
074                            BooleanQuery searchQuery, SearchContext searchContext)
075                    throws Exception {
076    
077                    addSearchTerm(searchQuery, searchContext, "city", false);
078                    addSearchTerm(searchQuery, searchContext, "country", false);
079                    addSearchTerm(searchQuery, searchContext, "emailAddress", false);
080                    addSearchTerm(searchQuery, searchContext, "firstName", false);
081                    addSearchTerm(searchQuery, searchContext, "fullName", false);
082                    addSearchTerm(searchQuery, searchContext, "lastName", false);
083                    addSearchTerm(searchQuery, searchContext, "middleName", false);
084                    addSearchTerm(searchQuery, searchContext, "region", false);
085                    addSearchTerm(searchQuery, searchContext, "screenName", false);
086                    addSearchTerm(searchQuery, searchContext, "street", false);
087                    addSearchTerm(searchQuery, searchContext, "zip", false);
088    
089                    LinkedHashMap<String, Object> params =
090                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
091    
092                    if (params != null) {
093                            String expandoAttributes = (String)params.get("expandoAttributes");
094    
095                            if (Validator.isNotNull(expandoAttributes)) {
096                                    addSearchExpando(searchQuery, searchContext, expandoAttributes);
097                            }
098                    }
099            }
100    
101            protected void addReindexCriteria(
102                    DynamicQuery dynamicQuery, long companyId) {
103    
104                    Property property = PropertyFactoryUtil.forName("companyId");
105    
106                    dynamicQuery.add(property.eq(companyId));
107            }
108    
109            @Override
110            protected void doDelete(Object obj) throws Exception {
111                    Contact contact = (Contact)obj;
112    
113                    deleteDocument(contact.getCompanyId(), contact.getContactId());
114            }
115    
116            @Override
117            protected Document doGetDocument(Object obj) throws Exception {
118                    Contact contact = (Contact)obj;
119    
120                    if (contact.isUser()) {
121                            User user = UserLocalServiceUtil.getUserByContactId(
122                                    contact.getContactId());
123    
124                            if (user.isDefaultUser() ||
125                                    (user.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
126    
127                                    return null;
128                            }
129                    }
130    
131                    Document document = getBaseModelDocument(PORTLET_ID, contact);
132    
133                    document.addKeyword(Field.COMPANY_ID, contact.getCompanyId());
134                    document.addDate(Field.MODIFIED_DATE, contact.getModifiedDate());
135                    document.addKeyword(Field.USER_ID, contact.getUserId());
136                    document.addKeyword(Field.USER_NAME, contact.getFullName());
137    
138                    document.addText("emailAddress", contact.getEmailAddress());
139                    document.addText("firstName", contact.getFirstName());
140                    document.addText("fullName", contact.getFullName());
141                    document.addText("jobTitle", contact.getJobTitle());
142                    document.addText("lastName", contact.getLastName());
143                    document.addText("middleName", contact.getMiddleName());
144    
145                    return document;
146            }
147    
148            @Override
149            protected String doGetSortField(String orderByCol) {
150                    if (orderByCol.equals("email-address")) {
151                            return "emailAddress";
152                    }
153                    else if (orderByCol.equals("first-name")) {
154                            return "firstName";
155                    }
156                    else if (orderByCol.equals("job-title")) {
157                            return "jobTitle";
158                    }
159                    else if (orderByCol.equals("last-name")) {
160                            return "lastName";
161                    }
162                    else {
163                            return orderByCol;
164                    }
165            }
166    
167            @Override
168            protected Summary doGetSummary(
169                    Document document, Locale locale, String snippet,
170                    PortletURL portletURL) {
171    
172                    return null;
173            }
174    
175            @Override
176            protected void doReindex(Object obj) throws Exception {
177                    Contact contact = (Contact)obj;
178    
179                    Document document = getDocument(contact);
180    
181                    if (document != null) {
182                            SearchEngineUtil.updateDocument(
183                                    getSearchEngineId(), contact.getCompanyId(), document);
184                    }
185            }
186    
187            @Override
188            protected void doReindex(String className, long classPK) throws Exception {
189                    Contact contact = ContactLocalServiceUtil.getContact(classPK);
190    
191                    doReindex(contact);
192            }
193    
194            @Override
195            protected void doReindex(String[] ids) throws Exception {
196                    long companyId = GetterUtil.getLong(ids[0]);
197    
198                    reindexContacts(companyId);
199            }
200    
201            @Override
202            protected String getPortletId(SearchContext searchContext) {
203                    return PORTLET_ID;
204            }
205    
206            protected void reindexContacts(long companyId) throws Exception {
207                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
208                            Contact.class, PACLClassLoaderUtil.getPortalClassLoader());
209    
210                    Projection minContactIdProjection = ProjectionFactoryUtil.min(
211                            "contactId");
212                    Projection maxContactIdProjection = ProjectionFactoryUtil.max(
213                            "contactId");
214    
215                    ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
216    
217                    projectionList.add(minContactIdProjection);
218                    projectionList.add(maxContactIdProjection);
219    
220                    dynamicQuery.setProjection(projectionList);
221    
222                    addReindexCriteria(dynamicQuery, companyId);
223    
224                    List<Object[]> results = ContactLocalServiceUtil.dynamicQuery(
225                            dynamicQuery);
226    
227                    Object[] minAndMaxContactIds = results.get(0);
228    
229                    if ((minAndMaxContactIds[0] == null) ||
230                            (minAndMaxContactIds[1] == null)) {
231    
232                            return;
233                    }
234    
235                    long minContactId = (Long)minAndMaxContactIds[0];
236                    long maxContactId = (Long)minAndMaxContactIds[1];
237    
238                    long startContactId = minContactId;
239                    long endContactId = startContactId + DEFAULT_INTERVAL;
240    
241                    while (startContactId <= maxContactId) {
242                            reindexContacts(companyId, startContactId, endContactId);
243    
244                            startContactId = endContactId;
245                            endContactId += DEFAULT_INTERVAL;
246                    }
247            }
248    
249            protected void reindexContacts(
250                            long companyId, long startContactId, long endContactId)
251                    throws Exception {
252    
253                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
254                            Contact.class, PACLClassLoaderUtil.getPortalClassLoader());
255    
256                    Property property = PropertyFactoryUtil.forName("contactId");
257    
258                    dynamicQuery.add(property.ge(startContactId));
259                    dynamicQuery.add(property.lt(endContactId));
260    
261                    addReindexCriteria(dynamicQuery, companyId);
262    
263                    List<Contact> contacts = ContactLocalServiceUtil.dynamicQuery(
264                            dynamicQuery);
265    
266                    if (contacts.isEmpty()) {
267                            return;
268                    }
269    
270                    Collection<Document> documents = new ArrayList<Document>(
271                            contacts.size());
272    
273                    for (Contact contact : contacts) {
274                            Document document = getDocument(contact);
275    
276                            if (document == null) {
277                                    continue;
278                            }
279    
280                            documents.add(document);
281                    }
282    
283                    SearchEngineUtil.updateDocuments(
284                            getSearchEngineId(), companyId, documents);
285            }
286    
287    }