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.calendar.util;
016    
017    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
018    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
019    import com.liferay.portal.kernel.dao.orm.Projection;
020    import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
021    import com.liferay.portal.kernel.dao.orm.ProjectionList;
022    import com.liferay.portal.kernel.dao.orm.Property;
023    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
024    import com.liferay.portal.kernel.search.BaseIndexer;
025    import com.liferay.portal.kernel.search.Document;
026    import com.liferay.portal.kernel.search.Field;
027    import com.liferay.portal.kernel.search.SearchContext;
028    import com.liferay.portal.kernel.search.SearchEngineUtil;
029    import com.liferay.portal.kernel.search.Summary;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.HtmlUtil;
032    import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
033    import com.liferay.portal.util.PortletKeys;
034    import com.liferay.portlet.calendar.model.CalEvent;
035    import com.liferay.portlet.calendar.service.CalEventLocalServiceUtil;
036    
037    import java.util.ArrayList;
038    import java.util.Collection;
039    import java.util.List;
040    import java.util.Locale;
041    
042    import javax.portlet.PortletURL;
043    
044    /**
045     * @author Brett Swaim
046     */
047    public class CalIndexer extends BaseIndexer {
048    
049            public static final String[] CLASS_NAMES = {CalEvent.class.getName()};
050    
051            public static final String PORTLET_ID = PortletKeys.CALENDAR;
052    
053            public CalIndexer() {
054                    setPermissionAware(true);
055            }
056    
057            public String[] getClassNames() {
058                    return CLASS_NAMES;
059            }
060    
061            public String getPortletId() {
062                    return PORTLET_ID;
063            }
064    
065            protected void addReindexCriteria(
066                    DynamicQuery dynamicQuery, long companyId) {
067    
068                    Property property = PropertyFactoryUtil.forName("companyId");
069    
070                    dynamicQuery.add(property.eq(companyId));
071            }
072    
073            @Override
074            protected void doDelete(Object obj) throws Exception {
075                    CalEvent event = (CalEvent)obj;
076    
077                    deleteDocument(event.getCompanyId(), event.getEventId());
078            }
079    
080            @Override
081            protected Document doGetDocument(Object obj) throws Exception {
082                    CalEvent event = (CalEvent)obj;
083    
084                    Document document = getBaseModelDocument(PORTLET_ID, event);
085    
086                    document.addText(
087                            Field.DESCRIPTION, HtmlUtil.extractText(event.getDescription()));
088                    document.addText(Field.TITLE, event.getTitle());
089                    document.addKeyword(Field.TYPE, event.getType());
090    
091                    return document;
092            }
093    
094            @Override
095            protected Summary doGetSummary(
096                    Document document, Locale locale, String snippet,
097                    PortletURL portletURL) {
098    
099                    String eventId = document.get(Field.ENTRY_CLASS_PK);
100    
101                    portletURL.setParameter("struts_action", "/calendar/view_event");
102                    portletURL.setParameter("eventId", eventId);
103    
104                    Summary summary = createSummary(
105                            document, Field.TITLE, Field.DESCRIPTION);
106    
107                    summary.setMaxContentLength(200);
108                    summary.setPortletURL(portletURL);
109    
110                    return summary;
111            }
112    
113            @Override
114            protected void doReindex(Object obj) throws Exception {
115                    CalEvent event = (CalEvent)obj;
116    
117                    Document document = getDocument(event);
118    
119                    SearchEngineUtil.updateDocument(
120                            getSearchEngineId(), event.getCompanyId(), document);
121            }
122    
123            @Override
124            protected void doReindex(String className, long classPK) throws Exception {
125                    CalEvent event = CalEventLocalServiceUtil.getEvent(classPK);
126    
127                    doReindex(event);
128            }
129    
130            @Override
131            protected void doReindex(String[] ids) throws Exception {
132                    long companyId = GetterUtil.getLong(ids[0]);
133    
134                    reindexEvents(companyId);
135            }
136    
137            @Override
138            protected String getPortletId(SearchContext searchContext) {
139                    return PORTLET_ID;
140            }
141    
142            protected void reindexEvents(long companyId) throws Exception {
143                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
144                            CalEvent.class, PACLClassLoaderUtil.getPortalClassLoader());
145    
146                    Projection minEventIdProjection = ProjectionFactoryUtil.min("eventId");
147                    Projection maxEventIdProjection = ProjectionFactoryUtil.max("eventId");
148    
149                    ProjectionList projectionList = ProjectionFactoryUtil.projectionList();
150    
151                    projectionList.add(minEventIdProjection);
152                    projectionList.add(maxEventIdProjection);
153    
154                    dynamicQuery.setProjection(projectionList);
155    
156                    addReindexCriteria(dynamicQuery, companyId);
157    
158                    List<Object[]> results = CalEventLocalServiceUtil.dynamicQuery(
159                            dynamicQuery);
160    
161                    Object[] minAndMaxEventIds = results.get(0);
162    
163                    if ((minAndMaxEventIds[0] == null) || (minAndMaxEventIds[1] == null)) {
164                            return;
165                    }
166    
167                    long minEventId = (Long)minAndMaxEventIds[0];
168                    long maxEventId = (Long)minAndMaxEventIds[1];
169    
170                    long startEventId = minEventId;
171                    long endEventId = startEventId + DEFAULT_INTERVAL;
172    
173                    while (startEventId <= maxEventId) {
174                            reindexEvents(companyId, startEventId, endEventId);
175    
176                            startEventId = endEventId;
177                            endEventId += DEFAULT_INTERVAL;
178                    }
179            }
180    
181            protected void reindexEvents(
182                            long companyId, long startEventId, long endEventId)
183                    throws Exception {
184    
185                    DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
186                            CalEvent.class, PACLClassLoaderUtil.getPortalClassLoader());
187    
188                    Property property = PropertyFactoryUtil.forName("eventId");
189    
190                    dynamicQuery.add(property.ge(startEventId));
191                    dynamicQuery.add(property.lt(endEventId));
192    
193                    addReindexCriteria(dynamicQuery, companyId);
194    
195                    List<CalEvent> events = CalEventLocalServiceUtil.dynamicQuery(
196                            dynamicQuery);
197    
198                    if (events.isEmpty()) {
199                            return;
200                    }
201    
202                    Collection<Document> documents = new ArrayList<Document>(events.size());
203    
204                    for (CalEvent event : events) {
205                            Document document = getDocument(event);
206    
207                            documents.add(document);
208                    }
209    
210                    SearchEngineUtil.updateDocuments(
211                            getSearchEngineId(), companyId, documents);
212            }
213    
214    }