001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.dynamicdatalists.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.language.LanguageUtil;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.search.BaseIndexer;
022    import com.liferay.portal.kernel.search.BooleanQuery;
023    import com.liferay.portal.kernel.search.Document;
024    import com.liferay.portal.kernel.search.Field;
025    import com.liferay.portal.kernel.search.SearchContext;
026    import com.liferay.portal.kernel.search.SearchEngineUtil;
027    import com.liferay.portal.kernel.search.Summary;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.LocaleUtil;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.workflow.WorkflowConstants;
033    import com.liferay.portal.util.PortletKeys;
034    import com.liferay.portlet.dynamicdatalists.model.DDLRecord;
035    import com.liferay.portlet.dynamicdatalists.model.DDLRecordConstants;
036    import com.liferay.portlet.dynamicdatalists.model.DDLRecordSet;
037    import com.liferay.portlet.dynamicdatalists.model.DDLRecordSetConstants;
038    import com.liferay.portlet.dynamicdatalists.model.DDLRecordVersion;
039    import com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalServiceUtil;
040    import com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalServiceUtil;
041    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
042    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
043    import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
044    import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
045    
046    import java.util.ArrayList;
047    import java.util.Collection;
048    import java.util.List;
049    import java.util.Locale;
050    
051    import javax.portlet.PortletURL;
052    
053    /**
054     * @author Marcellus Tavares
055     */
056    public class DDLIndexer extends BaseIndexer {
057    
058            public static final String[] CLASS_NAMES = {DDLRecord.class.getName()};
059    
060            public static final String PORTLET_ID = PortletKeys.DYNAMIC_DATA_LISTS;
061    
062            public DDLIndexer() {
063                    setFilterSearch(true);
064            }
065    
066            @Override
067            public String[] getClassNames() {
068                    return CLASS_NAMES;
069            }
070    
071            @Override
072            public String getPortletId() {
073                    return PORTLET_ID;
074            }
075    
076            @Override
077            public void postProcessContextQuery(
078                            BooleanQuery contextQuery, SearchContext searchContext)
079                    throws Exception {
080    
081                    int status = GetterUtil.getInteger(
082                            searchContext.getAttribute(Field.STATUS),
083                            WorkflowConstants.STATUS_APPROVED);
084    
085                    if (status != WorkflowConstants.STATUS_ANY) {
086                            contextQuery.addRequiredTerm(Field.STATUS, status);
087                    }
088    
089                    long recordSetId = GetterUtil.getLong(
090                            searchContext.getAttribute("recordSetId"));
091    
092                    if (recordSetId > 0) {
093                            contextQuery.addRequiredTerm("recordSetId", recordSetId);
094                    }
095            }
096    
097            @Override
098            public void postProcessSearchQuery(
099                            BooleanQuery searchQuery, SearchContext searchContext)
100                    throws Exception {
101    
102                    addSearchTerm(searchQuery, searchContext, Field.USER_NAME, false);
103    
104                    addSearchTerm(searchQuery, searchContext, "ddmContent", false);
105            }
106    
107            @Override
108            protected void doDelete(Object obj) throws Exception {
109                    DDLRecord record = (DDLRecord)obj;
110    
111                    deleteDocument(record.getCompanyId(), record.getRecordId());
112            }
113    
114            @Override
115            protected Document doGetDocument(Object obj) throws Exception {
116                    DDLRecord record = (DDLRecord)obj;
117    
118                    Document document = getBaseModelDocument(PORTLET_ID, record);
119    
120                    DDLRecordVersion recordVersion = record.getRecordVersion();
121    
122                    document.addKeyword(Field.STATUS, recordVersion.getStatus());
123                    document.addKeyword(Field.VERSION, recordVersion.getVersion());
124    
125                    document.addText(
126                            "ddmContent",
127                            extractDDMContent(recordVersion, LocaleUtil.getSiteDefault()));
128                    document.addKeyword("recordSetId", recordVersion.getRecordSetId());
129    
130                    DDLRecordSet recordSet = recordVersion.getRecordSet();
131    
132                    DDMStructure ddmStructure = recordSet.getDDMStructure();
133    
134                    Fields fields = StorageEngineUtil.getFields(
135                            recordVersion.getDDMStorageId());
136    
137                    DDMIndexerUtil.addAttributes(document, ddmStructure, fields);
138    
139                    return document;
140            }
141    
142            @Override
143            protected Summary doGetSummary(
144                    Document document, Locale locale, String snippet,
145                    PortletURL portletURL) {
146    
147                    long recordSetId = GetterUtil.getLong(document.get("recordSetId"));
148    
149                    String title = getTitle(recordSetId, locale);
150    
151                    String recordId = document.get(Field.ENTRY_CLASS_PK);
152    
153                    portletURL.setParameter(
154                            "struts_action", "/dynamic_data_lists/view_record");
155                    portletURL.setParameter("recordId", recordId);
156                    portletURL.setParameter("version", document.get(Field.VERSION));
157    
158                    Summary summary = createSummary(
159                            document, Field.TITLE, Field.DESCRIPTION);
160    
161                    summary.setMaxContentLength(200);
162                    summary.setPortletURL(portletURL);
163                    summary.setTitle(title);
164    
165                    return summary;
166            }
167    
168            @Override
169            protected void doReindex(Object obj) throws Exception {
170                    DDLRecord record = (DDLRecord)obj;
171    
172                    DDLRecordVersion recordVersion = record.getRecordVersion();
173    
174                    Document document = getDocument(record);
175    
176                    if (!recordVersion.isApproved()) {
177                            if (Validator.equals(
178                                            recordVersion.getVersion(),
179                                            DDLRecordConstants.VERSION_DEFAULT)) {
180    
181                                    SearchEngineUtil.deleteDocument(
182                                            getSearchEngineId(), record.getCompanyId(),
183                                            document.get(Field.UID));
184                            }
185    
186                            return;
187                    }
188    
189                    if (document != null) {
190                            SearchEngineUtil.updateDocument(
191                                    getSearchEngineId(), record.getCompanyId(), document);
192                    }
193            }
194    
195            @Override
196            protected void doReindex(String className, long classPK) throws Exception {
197                    DDLRecord record = DDLRecordLocalServiceUtil.getRecord(classPK);
198    
199                    doReindex(record);
200            }
201    
202            @Override
203            protected void doReindex(String[] ids) throws Exception {
204                    long companyId = GetterUtil.getLong(ids[0]);
205    
206                    reindexRecords(companyId);
207            }
208    
209            protected String extractDDMContent(
210                            DDLRecordVersion recordVersion, Locale locale)
211                    throws Exception {
212    
213                    Fields fields = StorageEngineUtil.getFields(
214                            recordVersion.getDDMStorageId());
215    
216                    if (fields == null) {
217                            return StringPool.BLANK;
218                    }
219    
220                    DDLRecordSet recordSet = recordVersion.getRecordSet();
221    
222                    return DDMIndexerUtil.extractAttributes(
223                            recordSet.getDDMStructure(), fields, locale);
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                            try {
294                                    Document document = getDocument(record);
295    
296                                    documents.add(document);
297                            }
298                            catch (PortalException pe) {
299                                    if (_log.isWarnEnabled()) {
300                                            _log.warn(
301                                                    "Unable to index dynamic data lists record " +
302                                                            record.getRecordId(),
303                                                    pe);
304                                    }
305                            }
306                    }
307    
308                    SearchEngineUtil.updateDocuments(
309                            getSearchEngineId(), companyId, documents);
310            }
311    
312            private static Log _log = LogFactoryUtil.getLog(DDLIndexer.class);
313    
314    }