001    /**
002     * Copyright (c) 2000-present 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.ActionableDynamicQuery;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.search.BaseIndexer;
022    import com.liferay.portal.kernel.search.BooleanClauseOccur;
023    import com.liferay.portal.kernel.search.BooleanQuery;
024    import com.liferay.portal.kernel.search.Document;
025    import com.liferay.portal.kernel.search.Field;
026    import com.liferay.portal.kernel.search.SearchContext;
027    import com.liferay.portal.kernel.search.SearchEngineUtil;
028    import com.liferay.portal.kernel.search.Summary;
029    import com.liferay.portal.kernel.search.WildcardQuery;
030    import com.liferay.portal.kernel.search.filter.BooleanFilter;
031    import com.liferay.portal.kernel.search.filter.QueryFilter;
032    import com.liferay.portal.kernel.search.filter.TermsFilter;
033    import com.liferay.portal.kernel.search.generic.WildcardQueryImpl;
034    import com.liferay.portal.kernel.spring.osgi.OSGiBeanProperties;
035    import com.liferay.portal.kernel.util.ArrayUtil;
036    import com.liferay.portal.kernel.util.GetterUtil;
037    import com.liferay.portal.kernel.util.ListUtil;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.model.Organization;
040    import com.liferay.portal.model.OrganizationConstants;
041    import com.liferay.portal.service.OrganizationLocalServiceUtil;
042    import com.liferay.portal.util.PropsValues;
043    
044    import java.util.ArrayList;
045    import java.util.Collection;
046    import java.util.HashMap;
047    import java.util.LinkedHashMap;
048    import java.util.List;
049    import java.util.Locale;
050    import java.util.Map;
051    
052    import javax.portlet.PortletRequest;
053    import javax.portlet.PortletResponse;
054    
055    /**
056     * @author Raymond Aug??
057     * @author Zsigmond Rab
058     * @author Hugo Huijser
059     */
060    @OSGiBeanProperties
061    public class OrganizationIndexer extends BaseIndexer {
062    
063            public static final String CLASS_NAME = Organization.class.getName();
064    
065            public OrganizationIndexer() {
066                    setCommitImmediately(true);
067                    setDefaultSelectedFieldNames(
068                            Field.COMPANY_ID, Field.ORGANIZATION_ID, Field.UID);
069                    setIndexerEnabled(PropsValues.ORGANIZATIONS_INDEXER_ENABLED);
070                    setPermissionAware(true);
071                    setStagingAware(false);
072            }
073    
074            @Override
075            public String getClassName() {
076                    return CLASS_NAME;
077            }
078    
079            @Override
080            public void postProcessContextBooleanFilter(
081                            BooleanFilter contextBooleanFilter, SearchContext searchContext)
082                    throws Exception {
083    
084                    LinkedHashMap<String, Object> params =
085                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
086    
087                    if (params == null) {
088                            return;
089                    }
090    
091                    List<Long> excludedOrganizationIds = (List<Long>)params.get(
092                            "excludedOrganizationIds");
093    
094                    if (ListUtil.isNotEmpty(excludedOrganizationIds)) {
095                            TermsFilter termsFilter = new TermsFilter("organizationId");
096    
097                            termsFilter.addValues(
098                                    ArrayUtil.toStringArray(
099                                            excludedOrganizationIds.toArray(
100                                                    new Long[excludedOrganizationIds.size()])));
101    
102                            contextBooleanFilter.add(termsFilter, BooleanClauseOccur.MUST_NOT);
103                    }
104    
105                    List<Organization> organizationsTree = (List<Organization>)params.get(
106                            "organizationsTree");
107    
108                    if (ListUtil.isNotEmpty(organizationsTree)) {
109                            BooleanFilter booleanFilter = new BooleanFilter();
110    
111                            for (Organization organization : organizationsTree) {
112                                    String treePath = organization.buildTreePath();
113    
114                                    WildcardQuery wildcardQuery = new WildcardQueryImpl(
115                                            Field.TREE_PATH, treePath);
116    
117                                    booleanFilter.add(new QueryFilter(wildcardQuery));
118                            }
119    
120                            contextBooleanFilter.add(booleanFilter, BooleanClauseOccur.MUST);
121                    }
122                    else {
123                            long parentOrganizationId = GetterUtil.getLong(
124                                    searchContext.getAttribute("parentOrganizationId"));
125    
126                            if (parentOrganizationId !=
127                                            OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
128    
129                                    contextBooleanFilter.addRequiredTerm(
130                                            "parentOrganizationId", parentOrganizationId);
131                            }
132                    }
133            }
134    
135            @Override
136            public void postProcessSearchQuery(
137                            BooleanQuery searchQuery, BooleanFilter fullQueryBooleanFilter,
138                            SearchContext searchContext)
139                    throws Exception {
140    
141                    addSearchTerm(searchQuery, searchContext, "city", false);
142                    addSearchTerm(searchQuery, searchContext, "country", false);
143                    addSearchTerm(searchQuery, searchContext, "name", false);
144                    addSearchTerm(searchQuery, searchContext, "region", false);
145                    addSearchTerm(searchQuery, searchContext, "street", false);
146                    addSearchTerm(searchQuery, searchContext, "type", false);
147                    addSearchTerm(searchQuery, searchContext, "zip", false);
148    
149                    LinkedHashMap<String, Object> params =
150                            (LinkedHashMap<String, Object>)searchContext.getAttribute("params");
151    
152                    if (params != null) {
153                            String expandoAttributes = (String)params.get("expandoAttributes");
154    
155                            if (Validator.isNotNull(expandoAttributes)) {
156                                    addSearchExpando(searchQuery, searchContext, expandoAttributes);
157                            }
158                    }
159            }
160    
161            @Override
162            protected void doDelete(Object obj) throws Exception {
163                    Organization organization = (Organization)obj;
164    
165                    deleteDocument(
166                            organization.getCompanyId(), organization.getOrganizationId());
167            }
168    
169            @Override
170            protected Document doGetDocument(Object obj) throws Exception {
171                    Organization organization = (Organization)obj;
172    
173                    Document document = getBaseModelDocument(CLASS_NAME, organization);
174    
175                    document.addKeyword(Field.COMPANY_ID, organization.getCompanyId());
176                    document.addText(Field.NAME, organization.getName());
177                    document.addKeyword(
178                            Field.ORGANIZATION_ID, organization.getOrganizationId());
179                    document.addKeyword(Field.TREE_PATH, organization.buildTreePath());
180                    document.addKeyword(Field.TYPE, organization.getType());
181    
182                    document.addKeyword(
183                            "parentOrganizationId", organization.getParentOrganizationId());
184    
185                    populateAddresses(
186                            document, organization.getAddresses(), organization.getRegionId(),
187                            organization.getCountryId());
188    
189                    return document;
190            }
191    
192            @Override
193            protected String doGetSortField(String orderByCol) {
194                    if (orderByCol.equals("name")) {
195                            return "name";
196                    }
197                    else if (orderByCol.equals("type")) {
198                            return "type";
199                    }
200                    else {
201                            return orderByCol;
202                    }
203            }
204    
205            @Override
206            protected Summary doGetSummary(
207                    Document document, Locale locale, String snippet,
208                    PortletRequest portletRequest, PortletResponse portletResponse) {
209    
210                    String title = document.get("name");
211    
212                    String content = null;
213    
214                    return new Summary(title, content);
215            }
216    
217            @Override
218            protected void doReindex(Object obj) throws Exception {
219                    if (obj instanceof Long) {
220                            long organizationId = (Long)obj;
221    
222                            Organization organization =
223                                    OrganizationLocalServiceUtil.getOrganization(organizationId);
224    
225                            doReindex(organization);
226                    }
227                    else if (obj instanceof long[]) {
228                            long[] organizationIds = (long[])obj;
229    
230                            Map<Long, Collection<Document>> documentsMap = new HashMap<>();
231    
232                            for (long organizationId : organizationIds) {
233                                    Organization organization =
234                                            OrganizationLocalServiceUtil.fetchOrganization(
235                                                    organizationId);
236    
237                                    if (organization == null) {
238                                            continue;
239                                    }
240    
241                                    Document document = getDocument(organization);
242    
243                                    long companyId = organization.getCompanyId();
244    
245                                    Collection<Document> documents = documentsMap.get(companyId);
246    
247                                    if (documents == null) {
248                                            documents = new ArrayList<>();
249    
250                                            documentsMap.put(companyId, documents);
251                                    }
252    
253                                    documents.add(document);
254                            }
255    
256                            for (Map.Entry<Long, Collection<Document>> entry :
257                                            documentsMap.entrySet()) {
258    
259                                    long companyId = entry.getKey();
260                                    Collection<Document> documents = entry.getValue();
261    
262                                    SearchEngineUtil.updateDocuments(
263                                            getSearchEngineId(), companyId, documents,
264                                            isCommitImmediately());
265                            }
266                    }
267                    else if (obj instanceof Organization) {
268                            Organization organization = (Organization)obj;
269    
270                            Document document = getDocument(organization);
271    
272                            SearchEngineUtil.updateDocument(
273                                    getSearchEngineId(), organization.getCompanyId(), document,
274                                    isCommitImmediately());
275                    }
276            }
277    
278            @Override
279            protected void doReindex(String className, long classPK) throws Exception {
280                    Organization organization =
281                            OrganizationLocalServiceUtil.getOrganization(classPK);
282    
283                    doReindex(organization);
284            }
285    
286            @Override
287            protected void doReindex(String[] ids) throws Exception {
288                    long companyId = GetterUtil.getLong(ids[0]);
289    
290                    reindexOrganizations(companyId);
291            }
292    
293            protected void reindexOrganizations(long companyId) throws Exception {
294                    final ActionableDynamicQuery actionableDynamicQuery =
295                            OrganizationLocalServiceUtil.getActionableDynamicQuery();
296    
297                    actionableDynamicQuery.setCompanyId(companyId);
298                    actionableDynamicQuery.setPerformActionMethod(
299                            new ActionableDynamicQuery.PerformActionMethod() {
300    
301                                    @Override
302                                    public void performAction(Object object) {
303                                            Organization organization = (Organization)object;
304    
305                                            try {
306                                                    Document document = getDocument(organization);
307    
308                                                    actionableDynamicQuery.addDocument(document);
309                                            }
310                                            catch (PortalException pe) {
311                                                    if (_log.isWarnEnabled()) {
312                                                            _log.warn(
313                                                                    "Unable to index organization " +
314                                                                            organization.getOrganizationId(),
315                                                                    pe);
316                                                    }
317                                            }
318                                    }
319    
320                            });
321                    actionableDynamicQuery.setSearchEngineId(getSearchEngineId());
322    
323                    actionableDynamicQuery.performActions();
324            }
325    
326            private static final Log _log = LogFactoryUtil.getLog(
327                    OrganizationIndexer.class);
328    
329    }