001    /**
002     * Copyright (c) 2000-2013 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.dynamicdatalists.util;
016    
017    import com.liferay.portal.kernel.language.LanguageUtil;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.search.BaseIndexer;
021    import com.liferay.portal.kernel.search.BooleanClauseOccur;
022    import com.liferay.portal.kernel.search.BooleanQuery;
023    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
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.util.GetterUtil;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.workflow.WorkflowConstants;
032    import com.liferay.portal.util.PortletKeys;
033    import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
034    import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
035    import com.liferay.portlet.dynamicdatalists.model.DDLRecordSetConstants;
036    import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
037    import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
038    import com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalServiceUtil;
039    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
040    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
041    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
042    import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
043    import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
044    
045    import java.util.ArrayList;
046    import java.util.Collection;
047    import java.util.List;
048    import java.util.Locale;
049    import java.util.Set;
050    import java.util.TreeSet;
051    
052    import javax.portlet.PortletURL;
053    
054    /**
055     * @author Marcellus Tavares
056     */
057    public class DDLIndexer extends BaseIndexer {
058    
059            public static final String[] CLASS_NAMES = {DDLRecord.class.getName()};
060    
061            public static final String PORTLET_ID = PortletKeys.DYNAMIC_DATA_LISTS;
062    
063            public DDLIndexer() {
064                    setFilterSearch(true);
065            }
066    
067            @Override
068            public String[] getClassNames() {
069                    return CLASS_NAMES;
070            }
071    
072            @Override
073            public String getPortletId() {
074                    return PORTLET_ID;
075            }
076    
077            @Override
078            public void postProcessContextQuery(
079                            BooleanQuery contextQuery, SearchContext searchContext)
080                    throws Exception {
081    
082                    int status = GetterUtil.getInteger(
083                            searchContext.getAttribute(Field.STATUS),
084                            WorkflowConstants.STATUS_APPROVED);
085    
086                    if (status != WorkflowConstants.STATUS_ANY) {
087                            contextQuery.addRequiredTerm(Field.STATUS, status);
088                    }
089    
090                    long recordSetId = GetterUtil.getLong(
091                            searchContext.getAttribute("recordSetId"));
092    
093                    if (recordSetId > 0) {
094                            contextQuery.addRequiredTerm("recordSetId", recordSetId);
095                    }
096            }
097    
098            @Override
099            public void postProcessSearchQuery(
100                            BooleanQuery searchQuery, SearchContext searchContext)
101                    throws Exception {
102    
103                    Set<DDMStructure> ddmStructuresSet = new TreeSet<DDMStructure>();
104    
105                    long recordSetId = GetterUtil.getLong(
106                            searchContext.getAttribute("recordSetId"));
107    
108                    if (recordSetId > 0) {
109                            DDLRecordSet recordSet = DDLRecordSetLocalServiceUtil.getRecordSet(
110                                    recordSetId);
111    
112                            ddmStructuresSet.add(recordSet.getDDMStructure());
113                    }
114                    else {
115                            long[] groupIds = searchContext.getGroupIds();
116    
117                            if ((groupIds != null) && (groupIds.length > 0)) {
118                                    List<DDMStructure> ddmStructures =
119                                            DDMStructureLocalServiceUtil.getStructures(groupIds);
120    
121                                    ddmStructuresSet.addAll(ddmStructures);
122                            }
123                    }
124    
125                    BooleanQuery ddmStructureQuery = BooleanQueryFactoryUtil.create(
126                            searchContext);
127    
128                    for (DDMStructure ddmStructure : ddmStructuresSet) {
129                            addSearchDDMStruture(searchQuery, searchContext, ddmStructure);
130                    }
131    
132                    if (ddmStructureQuery.hasClauses()) {
133                            searchQuery.add(ddmStructureQuery, BooleanClauseOccur.MUST);
134                    }
135    
136                    addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
137            }
138    
139            @Override
140            protected void doDelete(Object obj) throws Exception {
141                    DDLRecord record = (DDLRecord)obj;
142    
143                    deleteDocument(record.getCompanyId(), record.getRecordId());
144            }
145    
146            @Override
147            protected Document doGetDocument(Object obj) throws Exception {
148                    DDLRecord record = (DDLRecord)obj;
149    
150                    Document document = getBaseModelDocument(PORTLET_ID, record);
151    
152                    DDLRecordVersion recordVersion = record.getRecordVersion();
153    
154                    document.addKeyword(Field.STATUS, recordVersion.getStatus());
155                    document.addKeyword(Field.VERSION, recordVersion.getVersion());
156    
157                    document.addKeyword("recordSetId", recordVersion.getRecordSetId());
158    
159                    DDLRecordSet recordSet = recordVersion.getRecordSet();
160    
161                    DDMStructure ddmStructure = recordSet.getDDMStructure();
162    
163                    Fields fields = StorageEngineUtil.getFields(
164                            recordVersion.getDDMStorageId());
165    
166                    DDMIndexerUtil.addAttributes(document, ddmStructure, fields);
167    
168                    return document;
169            }
170    
171            @Override
172            protected Summary doGetSummary(
173                    Document document, Locale locale, String snippet,
174                    PortletURL portletURL) {
175    
176                    long recordSetId = GetterUtil.getLong(document.get("recordSetId"));
177    
178                    String title = getTitle(recordSetId, locale);
179    
180                    String recordId = document.get(Field.ENTRY_CLASS_PK);
181    
182                    portletURL.setParameter(
183                            "struts_action", "/dynamic_data_lists/view_record");
184                    portletURL.setParameter("recordId", recordId);
185    
186                    Summary summary = createSummary(
187                            document, Field.TITLE, Field.DESCRIPTION);
188    
189                    summary.setMaxContentLength(200);
190                    summary.setPortletURL(portletURL);
191                    summary.setTitle(title);
192    
193                    return summary;
194            }
195    
196            @Override
197            protected void doReindex(Object obj) throws Exception {
198                    DDLRecord record = (DDLRecord)obj;
199    
200                    DDLRecordVersion recordVersion = record.getRecordVersion();
201    
202                    if (!recordVersion.isApproved()) {
203                            return;
204                    }
205    
206                    Document document = getDocument(record);
207    
208                    if (document != null) {
209                            SearchEngineUtil.updateDocument(
210                                    getSearchEngineId(), record.getCompanyId(), document);
211                    }
212            }
213    
214            @Override
215            protected void doReindex(String className, long classPK) throws Exception {
216                    DDLRecord record = DDLRecordLocalServiceUtil.getRecord(classPK);
217    
218                    doReindex(record);
219            }
220    
221            @Override
222            protected void doReindex(String[] ids) throws Exception {
223                    long companyId = GetterUtil.getLong(ids[0]);
224    
225                    reindexRecords(companyId);
226            }
227    
228            @Override
229            protected String getPortletId(SearchContext searchContext) {
230                    return PORTLET_ID;
231            }
232    
233            protected String getTitle(long recordSetId, Locale locale) {
234                    try {
235                            DDLRecordSet recordSet = DDLRecordSetLocalServiceUtil.getRecordSet(
236                                    recordSetId);
237    
238                            DDMStructure ddmStructure = recordSet.getDDMStructure();
239    
240                            String ddmStructureName = ddmStructure.getName(locale);
241    
242                            String recordSetName = recordSet.getName(locale);
243    
244                            return LanguageUtil.format(
245                                    locale, "new-x-for-list-x",
246                                    new Object[] {ddmStructureName, recordSetName});
247                    }
248                    catch (Exception e) {
249                            _log.error(e, e);
250                    }
251    
252                    return StringPool.BLANK;
253            }
254    
255            protected void reindexRecords(long companyId) throws Exception {
256                    Long[] minAndMaxRecordIds =
257                            DDLRecordLocalServiceUtil.getMinAndMaxCompanyRecordIds(
258                                    companyId, WorkflowConstants.STATUS_APPROVED,
259                                    DDLRecordSetConstants.SCOPE_DYNAMIC_DATA_LISTS);
260    
261                    if ((minAndMaxRecordIds[0] == null) ||
262                            (minAndMaxRecordIds[1] == null)) {
263    
264                            return;
265                    }
266    
267                    long minRecordId = minAndMaxRecordIds[0];
268                    long maxRecordId = minAndMaxRecordIds[1];
269    
270                    long startRecordId = minRecordId;
271                    long endRecordId = startRecordId + DEFAULT_INTERVAL;
272    
273                    while (startRecordId <= maxRecordId) {
274                            reindexRecords(companyId, startRecordId, endRecordId);
275    
276                            startRecordId = endRecordId;
277                            endRecordId += DEFAULT_INTERVAL;
278                    }
279            }
280    
281            protected void reindexRecords(
282                            long companyId, long startRecordId, long endRecordId)
283                    throws Exception {
284    
285                    List<DDLRecord> records =
286                            DDLRecordLocalServiceUtil.getMinAndMaxCompanyRecords(
287                                    companyId, WorkflowConstants.STATUS_APPROVED,
288                                    DDLRecordSetConstants.SCOPE_DYNAMIC_DATA_LISTS, startRecordId,
289                                    endRecordId);
290    
291                    Collection<Document> documents = new ArrayList<Document>(
292                            records.size());
293    
294                    for (DDLRecord record : records) {
295                            Document document = getDocument(record);
296    
297                            documents.add(document);
298                    }
299    
300                    SearchEngineUtil.updateDocuments(
301                            getSearchEngineId(), companyId, documents);
302            }
303    
304            private static Log _log = LogFactoryUtil.getLog(DDLIndexer.class);
305    
306    }