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