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