001    /**
002     * Copyright (c) 2000-2012 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                            String name = recordSet.getName(locale);
237    
238                            return LanguageUtil.format(locale, "new-record-for-list-x", name);
239                    }
240                    catch (Exception e) {
241                            _log.error(e, e);
242                    }
243    
244                    return StringPool.BLANK;
245            }
246    
247            protected void reindexRecords(long companyId) throws Exception {
248                    Long[] minAndMaxRecordIds =
249                            DDLRecordLocalServiceUtil.getMinAndMaxCompanyRecordIds(
250                                    companyId, WorkflowConstants.STATUS_APPROVED,
251                                    DDLRecordSetConstants.SCOPE_DYNAMIC_DATA_LISTS);
252    
253                    if ((minAndMaxRecordIds[0] == null) ||
254                            (minAndMaxRecordIds[1] == null)) {
255    
256                            return;
257                    }
258    
259                    long minRecordId = minAndMaxRecordIds[0];
260                    long maxRecordId = minAndMaxRecordIds[1];
261    
262                    long startRecordId = minRecordId;
263                    long endRecordId = startRecordId + DEFAULT_INTERVAL;
264    
265                    while (startRecordId <= maxRecordId) {
266                            reindexRecords(companyId, startRecordId, endRecordId);
267    
268                            startRecordId = endRecordId;
269                            endRecordId += DEFAULT_INTERVAL;
270                    }
271            }
272    
273            protected void reindexRecords(
274                            long companyId, long startRecordId, long endRecordId)
275                    throws Exception {
276    
277                    List<DDLRecord> records =
278                            DDLRecordLocalServiceUtil.getMinAndMaxCompanyRecords(
279                                    companyId, WorkflowConstants.STATUS_APPROVED,
280                                    DDLRecordSetConstants.SCOPE_DYNAMIC_DATA_LISTS, startRecordId,
281                                    endRecordId);
282    
283                    Collection<Document> documents = new ArrayList<Document>(
284                            records.size());
285    
286                    for (DDLRecord record : records) {
287                            Document document = getDocument(record);
288    
289                            documents.add(document);
290                    }
291    
292                    SearchEngineUtil.updateDocuments(
293                            getSearchEngineId(), companyId, documents);
294            }
295    
296            private static Log _log = LogFactoryUtil.getLog(DDLIndexer.class);
297    
298    }