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