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.portal.kernel.search;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.kernel.util.WebKeys;
022    import com.liferay.portal.kernel.xml.Element;
023    import com.liferay.portal.model.Group;
024    import com.liferay.portal.model.Layout;
025    import com.liferay.portal.model.Portlet;
026    import com.liferay.portal.service.PortletLocalServiceUtil;
027    import com.liferay.portal.theme.ThemeDisplay;
028    import com.liferay.portlet.ratings.model.RatingsStats;
029    import com.liferay.portlet.ratings.service.RatingsStatsLocalServiceUtil;
030    
031    import java.util.Date;
032    import java.util.List;
033    import java.util.Locale;
034    
035    import javax.portlet.PortletURL;
036    
037    import javax.servlet.http.HttpServletRequest;
038    
039    /**
040     * @author Charles May
041     * @author Brian Wing Shun Chan
042     */
043    public abstract class HitsOpenSearchImpl extends BaseOpenSearchImpl {
044    
045            public Indexer getIndexer() {
046                    if (_log.isWarnEnabled()) {
047                            _log.warn(getClass() + " does not implement getIndexer()");
048                    }
049    
050                    return null;
051            }
052    
053            public abstract String getPortletId();
054    
055            public abstract String getSearchPath();
056    
057            public Summary getSummary(
058                            Indexer indexer, Document document, Locale locale, String snippet,
059                            PortletURL portletURL)
060                    throws SearchException {
061    
062                    return indexer.getSummary(document, locale, snippet, portletURL);
063            }
064    
065            public abstract String getTitle(String keywords);
066    
067            @Override
068            public String search(
069                            HttpServletRequest request, long groupId, long userId,
070                            String keywords, int startPage, int itemsPerPage, String format)
071                    throws SearchException {
072    
073                    try {
074                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
075                                    WebKeys.THEME_DISPLAY);
076    
077                            SearchContext searchContext = SearchContextFactory.getInstance(
078                                    request);
079    
080                            searchContext.setAttribute("paginationType", "more");
081    
082                            if (groupId == 0) {
083                                    searchContext.setGroupIds(null);
084                            }
085                            else {
086                                    searchContext.setGroupIds(new long[] {groupId});
087                            }
088    
089                            int end = startPage * itemsPerPage;
090    
091                            searchContext.setEnd(end);
092    
093                            Layout layout = themeDisplay.getLayout();
094    
095                            Group layoutGroup = layout.getGroup();
096    
097                            if (!layoutGroup.isStagingGroup() &&
098                                    !layoutGroup.isControlPanel()) {
099    
100                                    searchContext.setIncludeStagingGroups(false);
101                            }
102    
103                            searchContext.setKeywords(keywords);
104                            searchContext.setScopeStrict(false);
105    
106                            int start = (startPage * itemsPerPage) - itemsPerPage;
107    
108                            searchContext.setStart(start);
109    
110                            searchContext.setUserId(userId);
111    
112                            Indexer indexer = getIndexer();
113    
114                            if (indexer == null) {
115                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
116                                            themeDisplay.getCompanyId(), getPortletId());
117    
118                                    List<Indexer> indexers = portlet.getIndexerInstances();
119    
120                                    indexer = indexers.get(0);
121                            }
122    
123                            Hits results = indexer.search(searchContext);
124    
125                            String[] queryTerms = results.getQueryTerms();
126    
127                            int total = results.getLength();
128    
129                            Object[] values = addSearchResults(
130                                    queryTerms, keywords, startPage, itemsPerPage, total, start,
131                                    getTitle(keywords), getSearchPath(), format, themeDisplay);
132    
133                            com.liferay.portal.kernel.xml.Document doc =
134                                    (com.liferay.portal.kernel.xml.Document)values[0];
135                            Element root = (Element)values[1];
136    
137                            for (int i = 0; i < results.getDocs().length; i++) {
138                                    Document result = results.doc(i);
139    
140                                    String portletId = getPortletId();
141    
142                                    if (Validator.isNull(portletId)) {
143                                            portletId = result.get(Field.PORTLET_ID);
144                                    }
145    
146                                    String snippet = results.snippet(i);
147    
148                                    long resultGroupId = GetterUtil.getLong(
149                                            result.get(Field.GROUP_ID));
150    
151                                    if (resultGroupId == 0) {
152                                            resultGroupId = themeDisplay.getScopeGroupId();
153                                    }
154    
155                                    long resultScopeGroupId = GetterUtil.getLong(
156                                            result.get(Field.SCOPE_GROUP_ID));
157    
158                                    if (resultScopeGroupId == 0) {
159                                            resultScopeGroupId = themeDisplay.getScopeGroupId();
160                                    }
161    
162                                    PortletURL portletURL = getPortletURL(
163                                            request, portletId, resultScopeGroupId);
164    
165                                    Summary summary = getSummary(
166                                            indexer, result, themeDisplay.getLocale(), snippet,
167                                            portletURL);
168    
169                                    String title = summary.getTitle();
170                                    String url = getURL(
171                                            themeDisplay, resultScopeGroupId, result, portletURL);
172                                    Date modifiedDate = result.getDate(Field.MODIFIED_DATE);
173                                    String content = summary.getContent();
174    
175                                    String[] tags = new String[0];
176    
177                                    Field assetTagNamesField = result.getFields().get(
178                                            Field.ASSET_TAG_NAMES);
179    
180                                    if (assetTagNamesField != null) {
181                                            tags = assetTagNamesField.getValues();
182                                    }
183    
184                                    double ratings = 0.0;
185    
186                                    String entryClassName = result.get(Field.ENTRY_CLASS_NAME);
187                                    long entryClassPK = GetterUtil.getLong(
188                                            result.get(Field.ENTRY_CLASS_PK));
189    
190                                    if (Validator.isNotNull(entryClassName) && (entryClassPK > 0)) {
191                                            RatingsStats stats = RatingsStatsLocalServiceUtil.getStats(
192                                                    entryClassName, entryClassPK);
193    
194                                            ratings = stats.getTotalScore();
195                                    }
196    
197                                    double score = results.score(i);
198    
199                                    addSearchResult(
200                                            root, resultGroupId, resultScopeGroupId, entryClassName,
201                                            entryClassPK, title, url, modifiedDate, content, tags,
202                                            ratings, score, format);
203                            }
204    
205                            if (_log.isDebugEnabled()) {
206                                    _log.debug("Return\n" + doc.asXML());
207                            }
208    
209                            return doc.asXML();
210                    }
211                    catch (Exception e) {
212                            throw new SearchException(e);
213                    }
214            }
215    
216            protected String getURL(
217                            ThemeDisplay themeDisplay, long groupId, Document result,
218                            PortletURL portletURL)
219                    throws Exception {
220    
221                    return portletURL.toString();
222            }
223    
224            private static Log _log = LogFactoryUtil.getLog(HitsOpenSearchImpl.class);
225    
226    }