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            public String[] getClassNames() {
068                    return CLASS_NAMES;
069            }
070    
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                    Set<DDMStructure> ddmStructuresSet = new TreeSet<DDMStructure>();
102    
103                    long recordSetId = GetterUtil.getLong(
104                            searchContext.getAttribute("recordSetId"));
105    
106                    if (recordSetId > 0) {
107                            DDLRecordSet recordSet = DDLRecordSetLocalServiceUtil.getRecordSet(
108                                    recordSetId);
109    
110                            ddmStructuresSet.add(recordSet.getDDMStructure());
111                    }
112                    else {
113                            long[] groupIds = searchContext.getGroupIds();
114    
115                            if ((groupIds != null) && (groupIds.length > 0)) {
116                                    List<DDMStructure> ddmStructures =
117                                            DDMStructureLocalServiceUtil.getStructures(groupIds);
118    
119                                    ddmStructuresSet.addAll(ddmStructures);
120                            }
121                    }
122    
123                    BooleanQuery ddmStructureQuery = BooleanQueryFactoryUtil.create(
124                            searchContext);
125    
126                    for (DDMStructure ddmStructure : ddmStructuresSet) {
127                            addSearchDDMStruture(searchQuery, searchContext, ddmStructure);
128                    }
129    
130                    if (ddmStructureQuery.hasClauses()) {
131                            searchQuery.add(ddmStructureQuery, BooleanClauseOccur.MUST);
132                    }
133    
134                    addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
135            }
136    
137            @Override
138            protected void doDelete(Object obj) throws Exception {
139                    DDLRecord record = (DDLRecord)obj;
140    
141                    deleteDocument(record.getCompanyId(), record.getRecordId());
142            }
143    
144            @Override
145            protected Document doGetDocument(Object obj) throws Exception {
146                    DDLRecord record = (DDLRecord)obj;
147    
148                    Document document = getBaseModelDocument(PORTLET_ID, record);
149    
150                    DDLRecordVersion recordVersion = record.getRecordVersion();
151    
152                    document.addKeyword(Field.STATUS, recordVersion.getStatus());
153                    document.addKeyword(Field.VERSION, recordVersion.getVersion());
154    
155                    document.addKeyword("recordSetId", recordVersion.getRecordSetId());
156    
157                    DDLRecordSet recordSet = recordVersion.getRecordSet();
158    
159                    DDMStructure ddmStructure = recordSet.getDDMStructure();
160    
161                    Fields fields = StorageEngineUtil.getFields(
162                            recordVersion.getDDMStorageId());
163    
164                    DDMIndexerUtil.addAttributes(document, ddmStructure, fields);
165    
166                    return document;
167            }
168    
169            @Override
170            protected Summary doGetSummary(
171                    Document document, Locale locale, String snippet,
172                    PortletURL portletURL) {
173    
174                    long recordSetId = GetterUtil.getLong(document.get("recordSetId"));
175    
176                    String title = getTitle(recordSetId, locale);
177    
178                    String recordId = document.get(Field.ENTRY_CLASS_PK);
179    
180                    portletURL.setParameter(
181                            "struts_action", "/dynamic_data_lists/view_record");
182                    portletURL.setParameter("recordId", recordId);
183    
184                    Summary summary = createSummary(
185                            document, Field.TITLE, Field.DESCRIPTION);
186    
187                    summary.setMaxContentLength(200);
188                    summary.setPortletURL(portletURL);
189                    summary.setTitle(title);
190    
191                    return summary;
192            }
193    
194            @Override
195            protected void doReindex(Object obj) throws Exception {
196                    DDLRecord record = (DDLRecord)obj;
197    
198                    DDLRecordVersion recordVersion = record.getRecordVersion();
199    
200                    if (!recordVersion.isApproved()) {
201                            return;
202                    }
203    
204                    Document document = getDocument(record);
205    
206                    if (document != null) {
207                            SearchEngineUtil.updateDocument(
208                                    getSearchEngineId(), record.getCompanyId(), document);
209                    }
210            }
211    
212            @Override
213            protected void doReindex(String className, long classPK) throws Exception {
214                    DDLRecord record = DDLRecordLocalServiceUtil.getRecord(classPK);
215    
216                    doReindex(record);
217            }
218    
219            @Override
220            protected void doReindex(String[] ids) throws Exception {
221                    long companyId = GetterUtil.getLong(ids[0]);
222    
223                    reindexRecords(companyId);
224            }
225    
226            @Override
227            protected String getPortletId(SearchContext searchContext) {
228                    return PORTLET_ID;
229            }
230    
231            protected String getTitle(long recordSetId, Locale locale) {
232                    try {
233                            DDLRecordSet recordSet = DDLRecordSetLocalServiceUtil.getRecordSet(
234                                    recordSetId);
235    
236                            DDMStructure ddmStructure = recordSet.getDDMStructure();
237    
238                            String ddmStructureName = ddmStructure.getName(locale);
239    
240                            String recordSetName = recordSet.getName(locale);
241    
242                            return LanguageUtil.format(
243                                    locale, "new-x-for-list-x",
244                                    new Object[] {ddmStructureName, recordSetName});
245                    }
246                    catch (Exception e) {
247                            _log.error(e, e);
248                    }
249    
250                    return StringPool.BLANK;
251            }
252    
253            protected void reindexRecords(long companyId) throws Exception {
254                    Long[] minAndMaxRecordIds =
255                            DDLRecordLocalServiceUtil.getMinAndMaxCompanyRecordIds(
256                                    companyId, WorkflowConstants.STATUS_APPROVED,
257                                    DDLRecordSetConstants.SCOPE_DYNAMIC_DATA_LISTS);
258    
259                    if ((minAndMaxRecordIds[0] == null) ||
260                            (minAndMaxRecordIds[1] == null)) {
261    
262                            return;
263                    }
264    
265                    long minRecordId = minAndMaxRecordIds[0];
266                    long maxRecordId = minAndMaxRecordIds[1];
267    
268                    long startRecordId = minRecordId;
269                    long endRecordId = startRecordId + DEFAULT_INTERVAL;
270    
271                    while (startRecordId <= maxRecordId) {
272                            reindexRecords(companyId, startRecordId, endRecordId);
273    
274                            startRecordId = endRecordId;
275                            endRecordId += DEFAULT_INTERVAL;
276                    }
277            }
278    
279            protected void reindexRecords(
280                            long companyId, long startRecordId, long endRecordId)
281                    throws Exception {
282    
283                    List<DDLRecord> records =
284                            DDLRecordLocalServiceUtil.getMinAndMaxCompanyRecords(
285                                    companyId, WorkflowConstants.STATUS_APPROVED,
286                                    DDLRecordSetConstants.SCOPE_DYNAMIC_DATA_LISTS, startRecordId,
287                                    endRecordId);
288    
289                    Collection<Document> documents = new ArrayList<Document>(
290                            records.size());
291    
292                    for (DDLRecord record : records) {
293                            Document document = getDocument(record);
294    
295                            documents.add(document);
296                    }
297    
298                    SearchEngineUtil.updateDocuments(
299                            getSearchEngineId(), companyId, documents);
300            }
301    
302            private static Log _log = LogFactoryUtil.getLog(DDLIndexer.class);
303    
304    }