1   /**
2    * Copyright (c) 2000-2007 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.uuid.PortalUUIDUtil;
33  import com.liferay.portal.model.Layout;
34  import com.liferay.portal.service.LayoutLocalServiceUtil;
35  import com.liferay.portal.theme.ThemeDisplay;
36  import com.liferay.portal.util.WebKeys;
37  import com.liferay.portlet.PortletURLImpl;
38  import com.liferay.util.Http;
39  
40  import java.util.Date;
41  
42  import javax.portlet.PortletMode;
43  import javax.portlet.PortletModeException;
44  import javax.portlet.PortletURL;
45  import javax.portlet.WindowState;
46  import javax.portlet.WindowStateException;
47  
48  import javax.servlet.http.HttpServletRequest;
49  
50  import org.dom4j.DocumentHelper;
51  import org.dom4j.Element;
52  
53  /**
54   * <a href="BaseOpenSearchImpl.java.html"><b><i>View Source</i></b></a>
55   *
56   * @author Charles May
57   * @author Brian Wing Shun Chan
58   *
59   */
60  public abstract class BaseOpenSearchImpl implements OpenSearch {
61  
62      public boolean isEnabled() {
63          return true;
64      }
65  
66      public String search(HttpServletRequest req, String url)
67          throws SearchException {
68  
69          String keywords = GetterUtil.getString(
70              Http.getParameter(url, "keywords", false));
71          int startPage = GetterUtil.getInteger(
72              Http.getParameter(url, "p", false), 1);
73          int itemsPerPage = GetterUtil.getInteger(
74              Http.getParameter(url, "c", false), SearchContainer.DEFAULT_DELTA);
75  
76          return search(req, keywords, startPage, itemsPerPage);
77      }
78  
79      public abstract String search(
80              HttpServletRequest req, String keywords, int startPage,
81              int itemsPerPage)
82          throws SearchException;
83  
84      protected void addSearchResult(
85          Element root, String title, String link, Date updated, String summary,
86          double score) {
87  
88          // entry
89  
90          Element entry = OpenSearchUtil.addElement(
91              root, "entry", OpenSearchUtil.DEFAULT_NAMESPACE);
92  
93          // title
94  
95          OpenSearchUtil.addElement(
96              entry, "title", OpenSearchUtil.DEFAULT_NAMESPACE, title);
97  
98          // link
99  
100         Element entryLink = OpenSearchUtil.addElement(
101             entry, "link", OpenSearchUtil.DEFAULT_NAMESPACE);
102 
103         entryLink.addAttribute("href", link);
104 
105         // id
106 
107         OpenSearchUtil.addElement(
108             entry, "id", OpenSearchUtil.DEFAULT_NAMESPACE,
109             "urn:uuid:" + PortalUUIDUtil.generate());
110 
111         // updated
112 
113         OpenSearchUtil.addElement(
114             entry, "updated", OpenSearchUtil.DEFAULT_NAMESPACE, updated);
115 
116         // summary
117 
118         OpenSearchUtil.addElement(
119             entry, "summary", OpenSearchUtil.DEFAULT_NAMESPACE, summary);
120 
121         // relevance:score
122 
123         OpenSearchUtil.addElement(
124             entry, "score", OpenSearchUtil.RELEVANCE_NAMESPACE, score);
125     }
126 
127     protected Object[] addSearchResults(
128         String keywords, int startPage, int itemsPerPage, int total,
129         String title, String searchPath, ThemeDisplay themeDisplay) {
130 
131         return addSearchResults(
132             keywords, startPage, itemsPerPage, null, title, searchPath,
133             themeDisplay);
134     }
135 
136     protected Object[] addSearchResults(
137         String keywords, int startPage, int itemsPerPage, Hits hits,
138         String title, String searchPath, ThemeDisplay themeDisplay) {
139 
140         return addSearchResults(
141             keywords, startPage, itemsPerPage, 0, hits, title, searchPath,
142             themeDisplay);
143     }
144 
145     protected Object[] addSearchResults(
146         String keywords, int startPage, int itemsPerPage, int total, Hits hits,
147         String title, String searchPath, ThemeDisplay themeDisplay) {
148 
149         int begin = (startPage * itemsPerPage) - itemsPerPage;
150 
151         if (hits != null) {
152             int end = startPage * itemsPerPage;
153 
154             total = hits.getLength();
155 
156             if (end > total) {
157                 end = total;
158             }
159 
160             hits = hits.subset(begin, end);
161         }
162 
163         int totalPages = 0;
164 
165         if (total % itemsPerPage == 0) {
166             totalPages = total / itemsPerPage;
167         }
168         else {
169             totalPages = (total / itemsPerPage) + 1;
170         }
171 
172         int previousPage = startPage - 1;
173         int nextPage = startPage + 1;
174 
175         // Create document
176 
177         org.dom4j.Document doc = DocumentHelper.createDocument();
178 
179         // feed
180 
181         Element root = doc.addElement("feed");
182 
183         root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.DEFAULT_NAMESPACE));
184         root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.OS_NAMESPACE));
185         root.add(
186             OpenSearchUtil.getNamespace(OpenSearchUtil.RELEVANCE_NAMESPACE));
187 
188         // title
189 
190         OpenSearchUtil.addElement(
191             root, "title", OpenSearchUtil.DEFAULT_NAMESPACE, title);
192 
193         // updated
194 
195         OpenSearchUtil.addElement(
196             root, "updated", OpenSearchUtil.DEFAULT_NAMESPACE, new Date());
197 
198         // author
199 
200         Element author = OpenSearchUtil.addElement(
201             root, "author", OpenSearchUtil.DEFAULT_NAMESPACE);
202 
203         // name
204 
205         OpenSearchUtil.addElement(
206             author, "name", OpenSearchUtil.DEFAULT_NAMESPACE,
207             themeDisplay.getUserId());
208 
209         // id
210 
211         OpenSearchUtil.addElement(
212             root, "id", OpenSearchUtil.DEFAULT_NAMESPACE,
213             "urn:uuid:" + PortalUUIDUtil.generate());
214 
215         // opensearch:totalResults
216 
217         OpenSearchUtil.addElement(
218             root, "totalResults", OpenSearchUtil.OS_NAMESPACE, total);
219 
220         // opensearch:startIndex
221 
222         OpenSearchUtil.addElement(
223             root, "startIndex", OpenSearchUtil.OS_NAMESPACE, begin + 1);
224 
225         // opensearch:itemsPerPage
226 
227         OpenSearchUtil.addElement(
228             root, "itemsPerPage", OpenSearchUtil.OS_NAMESPACE, itemsPerPage);
229 
230         // opensearch:Query
231 
232         Element query = OpenSearchUtil.addElement(
233             root, "Query", OpenSearchUtil.OS_NAMESPACE);
234 
235         query.addAttribute("role", "request");
236         query.addAttribute("searchTerms", keywords);
237         query.addAttribute("startPage", String.valueOf(startPage));
238 
239         // links
240 
241         String searchURL = themeDisplay.getURLPortal() + searchPath;
242 
243         OpenSearchUtil.addLink(
244             root, searchURL, "self", keywords, startPage, itemsPerPage);
245         OpenSearchUtil.addLink(
246             root, searchURL, "first", keywords, 1, itemsPerPage);
247 
248         if (previousPage > 0) {
249             OpenSearchUtil.addLink(
250                 root, searchURL, "previous", keywords, previousPage,
251                 itemsPerPage);
252         }
253 
254         if (nextPage <= totalPages) {
255             OpenSearchUtil.addLink(
256                 root, searchURL, "next", keywords, nextPage, itemsPerPage);
257         }
258 
259         OpenSearchUtil.addLink(
260             root, searchURL, "last", keywords, totalPages, itemsPerPage);
261 
262         Element link = OpenSearchUtil.addElement(
263             root, "link", OpenSearchUtil.DEFAULT_NAMESPACE);
264 
265         link.addAttribute("rel", "search");
266         link.addAttribute("href", searchPath + "_description.xml");
267         link.addAttribute("type", "application/opensearchdescription+xml");
268 
269         return new Object[] {hits, doc, root};
270     }
271 
272     protected PortletURL getPortletURL(HttpServletRequest req, String portletId)
273         throws PortalException, PortletModeException, SystemException,
274                WindowStateException {
275 
276         return getPortletURL(req, portletId, 0);
277     }
278 
279     protected PortletURL getPortletURL(
280             HttpServletRequest req, String portletId, long groupId)
281         throws PortalException, PortletModeException, SystemException,
282                WindowStateException {
283 
284         long plid = LayoutLocalServiceUtil.getDefaultPlid(groupId, true);
285 
286         if (plid == 0) {
287             plid = LayoutLocalServiceUtil.getDefaultPlid(groupId, false);
288         }
289 
290         if (plid == 0) {
291             Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
292 
293             if (layout != null) {
294                 plid = layout.getPlid();
295             }
296         }
297 
298         PortletURL portletURL = new PortletURLImpl(req, portletId, plid, false);
299 
300         portletURL.setWindowState(WindowState.MAXIMIZED);
301         portletURL.setPortletMode(PortletMode.VIEW);
302 
303         return portletURL;
304     }
305 
306 }