1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.search;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.dao.search.SearchContainer;
28  import com.liferay.portal.kernel.search.Hits;
29  import com.liferay.portal.kernel.search.OpenSearch;
30  import com.liferay.portal.kernel.search.SearchException;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.HttpUtil;
33  import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
34  import com.liferay.portal.model.Layout;
35  import com.liferay.portal.service.LayoutLocalServiceUtil;
36  import com.liferay.portal.theme.ThemeDisplay;
37  import com.liferay.portal.util.WebKeys;
38  import com.liferay.portlet.PortletURLImpl;
39  
40  import java.util.Date;
41  
42  import javax.portlet.PortletMode;
43  import javax.portlet.PortletModeException;
44  import javax.portlet.PortletRequest;
45  import javax.portlet.PortletURL;
46  import javax.portlet.WindowState;
47  import javax.portlet.WindowStateException;
48  
49  import javax.servlet.http.HttpServletRequest;
50  
51  import org.dom4j.DocumentHelper;
52  import org.dom4j.Element;
53  
54  /**
55   * <a href="BaseOpenSearchImpl.java.html"><b><i>View Source</i></b></a>
56   *
57   * @author Charles May
58   * @author Brian Wing Shun Chan
59   *
60   */
61  public abstract class BaseOpenSearchImpl implements OpenSearch {
62  
63      public boolean isEnabled() {
64          return true;
65      }
66  
67      public String search(HttpServletRequest req, String url)
68          throws SearchException {
69  
70          String keywords = GetterUtil.getString(
71              HttpUtil.getParameter(url, "keywords", false));
72          int startPage = GetterUtil.getInteger(
73              HttpUtil.getParameter(url, "p", false), 1);
74          int itemsPerPage = GetterUtil.getInteger(
75              HttpUtil.getParameter(url, "c", false),
76              SearchContainer.DEFAULT_DELTA);
77  
78          return search(req, keywords, startPage, itemsPerPage);
79      }
80  
81      public abstract String search(
82              HttpServletRequest req, String keywords, int startPage,
83              int itemsPerPage)
84          throws SearchException;
85  
86      protected void addSearchResult(
87          Element root, String title, String link, Date updated, String summary,
88          double score) {
89  
90          // entry
91  
92          Element entry = OpenSearchUtil.addElement(
93              root, "entry", OpenSearchUtil.DEFAULT_NAMESPACE);
94  
95          // title
96  
97          OpenSearchUtil.addElement(
98              entry, "title", OpenSearchUtil.DEFAULT_NAMESPACE, title);
99  
100         // link
101 
102         Element entryLink = OpenSearchUtil.addElement(
103             entry, "link", OpenSearchUtil.DEFAULT_NAMESPACE);
104 
105         entryLink.addAttribute("href", link);
106 
107         // id
108 
109         OpenSearchUtil.addElement(
110             entry, "id", OpenSearchUtil.DEFAULT_NAMESPACE,
111             "urn:uuid:" + PortalUUIDUtil.generate());
112 
113         // updated
114 
115         OpenSearchUtil.addElement(
116             entry, "updated", OpenSearchUtil.DEFAULT_NAMESPACE, updated);
117 
118         // summary
119 
120         OpenSearchUtil.addElement(
121             entry, "summary", OpenSearchUtil.DEFAULT_NAMESPACE, summary);
122 
123         // relevance:score
124 
125         OpenSearchUtil.addElement(
126             entry, "score", OpenSearchUtil.RELEVANCE_NAMESPACE, score);
127     }
128 
129     protected Object[] addSearchResults(
130         String keywords, int startPage, int itemsPerPage, int total,
131         String title, String searchPath, ThemeDisplay themeDisplay) {
132 
133         return addSearchResults(
134             keywords, startPage, itemsPerPage, null, title, searchPath,
135             themeDisplay);
136     }
137 
138     protected Object[] addSearchResults(
139         String keywords, int startPage, int itemsPerPage, Hits hits,
140         String title, String searchPath, ThemeDisplay themeDisplay) {
141 
142         return addSearchResults(
143             keywords, startPage, itemsPerPage, 0, hits, title, searchPath,
144             themeDisplay);
145     }
146 
147     protected Object[] addSearchResults(
148         String keywords, int startPage, int itemsPerPage, int total, Hits hits,
149         String title, String searchPath, ThemeDisplay themeDisplay) {
150 
151         int begin = (startPage * itemsPerPage) - itemsPerPage;
152 
153         if (hits != null) {
154             int end = startPage * itemsPerPage;
155 
156             total = hits.getLength();
157 
158             if (end > total) {
159                 end = total;
160             }
161 
162             hits = hits.subset(begin, end);
163         }
164 
165         int totalPages = 0;
166 
167         if (total % itemsPerPage == 0) {
168             totalPages = total / itemsPerPage;
169         }
170         else {
171             totalPages = (total / itemsPerPage) + 1;
172         }
173 
174         int previousPage = startPage - 1;
175         int nextPage = startPage + 1;
176 
177         // Create document
178 
179         org.dom4j.Document doc = DocumentHelper.createDocument();
180 
181         // feed
182 
183         Element root = doc.addElement("feed");
184 
185         root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.DEFAULT_NAMESPACE));
186         root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.OS_NAMESPACE));
187         root.add(
188             OpenSearchUtil.getNamespace(OpenSearchUtil.RELEVANCE_NAMESPACE));
189 
190         // title
191 
192         OpenSearchUtil.addElement(
193             root, "title", OpenSearchUtil.DEFAULT_NAMESPACE, title);
194 
195         // updated
196 
197         OpenSearchUtil.addElement(
198             root, "updated", OpenSearchUtil.DEFAULT_NAMESPACE, new Date());
199 
200         // author
201 
202         Element author = OpenSearchUtil.addElement(
203             root, "author", OpenSearchUtil.DEFAULT_NAMESPACE);
204 
205         // name
206 
207         OpenSearchUtil.addElement(
208             author, "name", OpenSearchUtil.DEFAULT_NAMESPACE,
209             themeDisplay.getUserId());
210 
211         // id
212 
213         OpenSearchUtil.addElement(
214             root, "id", OpenSearchUtil.DEFAULT_NAMESPACE,
215             "urn:uuid:" + PortalUUIDUtil.generate());
216 
217         // opensearch:totalResults
218 
219         OpenSearchUtil.addElement(
220             root, "totalResults", OpenSearchUtil.OS_NAMESPACE, total);
221 
222         // opensearch:startIndex
223 
224         OpenSearchUtil.addElement(
225             root, "startIndex", OpenSearchUtil.OS_NAMESPACE, begin + 1);
226 
227         // opensearch:itemsPerPage
228 
229         OpenSearchUtil.addElement(
230             root, "itemsPerPage", OpenSearchUtil.OS_NAMESPACE, itemsPerPage);
231 
232         // opensearch:Query
233 
234         Element query = OpenSearchUtil.addElement(
235             root, "Query", OpenSearchUtil.OS_NAMESPACE);
236 
237         query.addAttribute("role", "request");
238         query.addAttribute("searchTerms", keywords);
239         query.addAttribute("startPage", String.valueOf(startPage));
240 
241         // links
242 
243         String searchURL = themeDisplay.getURLPortal() + searchPath;
244 
245         OpenSearchUtil.addLink(
246             root, searchURL, "self", keywords, startPage, itemsPerPage);
247         OpenSearchUtil.addLink(
248             root, searchURL, "first", keywords, 1, itemsPerPage);
249 
250         if (previousPage > 0) {
251             OpenSearchUtil.addLink(
252                 root, searchURL, "previous", keywords, previousPage,
253                 itemsPerPage);
254         }
255 
256         if (nextPage <= totalPages) {
257             OpenSearchUtil.addLink(
258                 root, searchURL, "next", keywords, nextPage, itemsPerPage);
259         }
260 
261         OpenSearchUtil.addLink(
262             root, searchURL, "last", keywords, totalPages, itemsPerPage);
263 
264         Element link = OpenSearchUtil.addElement(
265             root, "link", OpenSearchUtil.DEFAULT_NAMESPACE);
266 
267         link.addAttribute("rel", "search");
268         link.addAttribute("href", searchPath + "_description.xml");
269         link.addAttribute("type", "application/opensearchdescription+xml");
270 
271         return new Object[] {hits, doc, root};
272     }
273 
274     protected PortletURL getPortletURL(HttpServletRequest req, String portletId)
275         throws PortalException, PortletModeException, SystemException,
276                WindowStateException {
277 
278         return getPortletURL(req, portletId, 0);
279     }
280 
281     protected PortletURL getPortletURL(
282             HttpServletRequest req, String portletId, long groupId)
283         throws PortalException, PortletModeException, SystemException,
284                WindowStateException {
285 
286         long plid = LayoutLocalServiceUtil.getDefaultPlid(
287             groupId, false, portletId);
288 
289         if (plid == 0) {
290             plid = LayoutLocalServiceUtil.getDefaultPlid(
291                 groupId, true, portletId);
292         }
293 
294         if (plid == 0) {
295             Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
296 
297             if (layout != null) {
298                 plid = layout.getPlid();
299             }
300         }
301 
302         PortletURL portletURL = new PortletURLImpl(
303             req, portletId, plid, PortletRequest.RENDER_PHASE);
304 
305         portletURL.setWindowState(WindowState.MAXIMIZED);
306         portletURL.setPortletMode(PortletMode.VIEW);
307 
308         return portletURL;
309     }
310 
311 }