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.search;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.search.BaseOpenSearchImpl;
020    import com.liferay.portal.kernel.search.Document;
021    import com.liferay.portal.kernel.search.Field;
022    import com.liferay.portal.kernel.search.Hits;
023    import com.liferay.portal.kernel.search.Indexer;
024    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
025    import com.liferay.portal.kernel.search.SearchException;
026    import com.liferay.portal.kernel.search.Summary;
027    import com.liferay.portal.kernel.util.CharPool;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.StringBundler;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.xml.Element;
033    import com.liferay.portal.model.Layout;
034    import com.liferay.portal.model.Portlet;
035    import com.liferay.portal.service.CompanyLocalServiceUtil;
036    import com.liferay.portal.service.GroupLocalServiceUtil;
037    import com.liferay.portal.service.LayoutLocalServiceUtil;
038    import com.liferay.portal.service.PortletLocalServiceUtil;
039    import com.liferay.portal.theme.ThemeDisplay;
040    import com.liferay.portal.util.PortalUtil;
041    import com.liferay.portal.util.PortletKeys;
042    import com.liferay.portal.util.WebKeys;
043    import com.liferay.portlet.journal.model.JournalArticle;
044    import com.liferay.portlet.journal.model.JournalArticleConstants;
045    import com.liferay.portlet.journal.service.JournalArticleServiceUtil;
046    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
047    
048    import java.util.Date;
049    import java.util.List;
050    
051    import javax.portlet.PortletURL;
052    
053    import javax.servlet.http.HttpServletRequest;
054    
055    /**
056     * @author Charles May
057     * @author Brian Wing Shun Chan
058     */
059    public class PortalOpenSearchImpl extends BaseOpenSearchImpl {
060    
061            public static final String SEARCH_PATH = "/c/search/open_search";
062    
063            @Override
064            public String search(
065                            HttpServletRequest request, long groupId, long userId,
066                            String keywords, int startPage, int itemsPerPage, String format)
067                    throws SearchException {
068    
069                    try {
070                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
071                                    WebKeys.THEME_DISPLAY);
072    
073                            int start = (startPage * itemsPerPage) - itemsPerPage;
074                            int end = startPage * itemsPerPage;
075    
076                            Hits results = CompanyLocalServiceUtil.search(
077                                    themeDisplay.getCompanyId(), userId, keywords, start, end);
078    
079                            String[] queryTerms = results.getQueryTerms();
080    
081                            int total = results.getLength();
082    
083                            Object[] values = addSearchResults(
084                                    queryTerms, keywords, startPage, itemsPerPage, total, start,
085                                    "Liferay Portal Search: " + keywords, SEARCH_PATH, format,
086                                    themeDisplay);
087    
088                            com.liferay.portal.kernel.xml.Document doc =
089                                    (com.liferay.portal.kernel.xml.Document)values[0];
090                            Element root = (Element)values[1];
091    
092                            for (int i = 0; i < results.getDocs().length; i++) {
093                                    Document result = results.doc(i);
094    
095                                    String portletId = result.get(Field.PORTLET_ID);
096    
097                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
098                                            themeDisplay.getCompanyId(), portletId);
099    
100                                    if (portlet == null) {
101                                            continue;
102                                    }
103    
104                                    String portletTitle = PortalUtil.getPortletTitle(
105                                            portletId, themeDisplay.getUser());
106    
107                                    long resultGroupId = GetterUtil.getLong(
108                                            result.get(Field.GROUP_ID));
109    
110                                    long resultScopeGroupId = GetterUtil.getLong(
111                                            result.get(Field.SCOPE_GROUP_ID));
112    
113                                    if (resultScopeGroupId == 0) {
114                                            resultScopeGroupId = themeDisplay.getScopeGroupId();
115                                    }
116    
117                                    String entryClassName = GetterUtil.getString(
118                                            result.get(Field.ENTRY_CLASS_NAME));
119    
120                                    long entryClassPK = GetterUtil.getLong(
121                                            result.get(Field.ENTRY_CLASS_PK));
122    
123                                    String title = StringPool.BLANK;
124    
125                                    PortletURL portletURL = getPortletURL(
126                                            request, portletId, resultScopeGroupId);
127    
128                                    String url = portletURL.toString();
129    
130                                    Date modifiedDate = result.getDate(Field.MODIFIED_DATE);
131    
132                                    String content = StringPool.BLANK;
133    
134                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
135                                            entryClassName);
136    
137                                    if (indexer != null) {
138                                            String snippet = result.get(Field.SNIPPET);
139    
140                                            Summary summary = indexer.getSummary(
141                                                    result, themeDisplay.getLocale(), snippet, portletURL);
142    
143                                            if (summary == null) {
144                                                    continue;
145                                            }
146    
147                                            title = summary.getTitle();
148                                            url = portletURL.toString();
149                                            content = summary.getContent();
150    
151                                            if (portlet.getPortletId().equals(PortletKeys.JOURNAL)) {
152                                                    url = getJournalURL(
153                                                            themeDisplay, resultGroupId, result);
154                                            }
155                                    }
156    
157                                    double score = results.score(i);
158    
159                                    addSearchResult(
160                                            root, resultGroupId, resultScopeGroupId, entryClassName,
161                                            entryClassPK,
162                                            portletTitle + " " + CharPool.RAQUO + " " + title, url,
163                                            modifiedDate, content, score, format);
164                            }
165    
166                            if (_log.isDebugEnabled()) {
167                                    _log.debug("Return\n" + doc.asXML());
168                            }
169    
170                            return doc.asXML();
171                    }
172                    catch (Exception e) {
173                            throw new SearchException(e);
174                    }
175            }
176    
177            protected String getJournalURL(
178                            ThemeDisplay themeDisplay, long groupId, Document result)
179                    throws Exception {
180    
181                    String articleId = result.get("articleId");
182    
183                    JournalArticle article = JournalArticleServiceUtil.getArticle(
184                            groupId, articleId);
185    
186                    if (Validator.isNotNull(article.getLayoutUuid())) {
187                            String groupFriendlyURL = PortalUtil.getGroupFriendlyURL(
188                                    GroupLocalServiceUtil.getGroup(article.getGroupId()), false,
189                                    themeDisplay);
190    
191                            return groupFriendlyURL.concat(
192                                    JournalArticleConstants.CANONICAL_URL_SEPARATOR).concat(
193                                            article.getUrlTitle());
194                    }
195    
196                    Layout layout = themeDisplay.getLayout();
197    
198                    List<Long> hitLayoutIds =
199                            JournalContentSearchLocalServiceUtil.getLayoutIds(
200                                    layout.getGroupId(), layout.isPrivateLayout(), articleId);
201    
202                    if (!hitLayoutIds.isEmpty()) {
203                            Long hitLayoutId = hitLayoutIds.get(0);
204    
205                            Layout hitLayout = LayoutLocalServiceUtil.getLayout(
206                                    layout.getGroupId(), layout.isPrivateLayout(),
207                                    hitLayoutId.longValue());
208    
209                            return PortalUtil.getLayoutURL(hitLayout, themeDisplay);
210                    }
211    
212                    StringBundler sb = new StringBundler(7);
213    
214                    sb.append(themeDisplay.getPathMain());
215                    sb.append("/journal/view_article_content?groupId=");
216                    sb.append(groupId);
217                    sb.append("&articleId=");
218                    sb.append(articleId);
219                    sb.append("&version=");
220    
221                    String version = result.get("version");
222    
223                    sb.append(version);
224    
225                    return sb.toString();
226            }
227    
228            private static Log _log = LogFactoryUtil.getLog(PortalOpenSearchImpl.class);
229    
230    }