001
014
015 package com.liferay.portal.kernel.search;
016
017 import com.liferay.portal.kernel.dao.search.SearchContainer;
018 import com.liferay.portal.kernel.util.GetterUtil;
019 import com.liferay.portal.kernel.util.HttpUtil;
020 import com.liferay.portal.kernel.util.PropsUtil;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023 import com.liferay.portal.kernel.util.WebKeys;
024 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
025 import com.liferay.portal.kernel.xml.Document;
026 import com.liferay.portal.kernel.xml.Element;
027 import com.liferay.portal.kernel.xml.SAXReaderUtil;
028 import com.liferay.portal.model.Layout;
029 import com.liferay.portal.service.LayoutServiceUtil;
030 import com.liferay.portal.service.UserLocalServiceUtil;
031 import com.liferay.portal.theme.ThemeDisplay;
032 import com.liferay.portal.util.PortalUtil;
033 import com.liferay.portlet.PortletURLFactoryUtil;
034
035 import java.util.Date;
036
037 import javax.portlet.PortletMode;
038 import javax.portlet.PortletRequest;
039 import javax.portlet.PortletURL;
040 import javax.portlet.WindowState;
041
042 import javax.servlet.http.HttpServletRequest;
043
044
048 public abstract class BaseOpenSearchImpl implements OpenSearch {
049
050 public BaseOpenSearchImpl() {
051 _enabled = GetterUtil.getBoolean(
052 PropsUtil.get(getClass().getName()), true);
053 }
054
055 @Override
056 public boolean isEnabled() {
057 return _enabled;
058 }
059
060 @Override
061 public abstract String search(
062 HttpServletRequest request, long groupId, long userId,
063 String keywords, int startPage, int itemsPerPage, String format)
064 throws SearchException;
065
066 @Override
067 public String search(
068 HttpServletRequest request, long userId, String keywords,
069 int startPage, int itemsPerPage, String format)
070 throws SearchException {
071
072 return search(
073 request, 0, userId, keywords, startPage, itemsPerPage, format);
074 }
075
076 @Override
077 public String search(HttpServletRequest request, String url)
078 throws SearchException {
079
080 try {
081 long userId = PortalUtil.getUserId(request);
082
083 if (userId == 0) {
084 long companyId = PortalUtil.getCompanyId(request);
085
086 userId = UserLocalServiceUtil.getDefaultUserId(companyId);
087 }
088
089 String keywords = GetterUtil.getString(
090 HttpUtil.getParameter(url, "keywords", false));
091 int startPage = GetterUtil.getInteger(
092 HttpUtil.getParameter(url, "p", false), 1);
093 int itemsPerPage = GetterUtil.getInteger(
094 HttpUtil.getParameter(url, "c", false),
095 SearchContainer.DEFAULT_DELTA);
096 String format = GetterUtil.getString(
097 HttpUtil.getParameter(url, "format", false));
098
099 return search(
100 request, userId, keywords, startPage, itemsPerPage, format);
101 }
102 catch (SearchException se) {
103 throw se;
104 }
105 catch (Exception e) {
106 throw new SearchException(e);
107 }
108 }
109
110 protected void addSearchResult(
111 Element root, long groupId, long scopeGroupId, String entryClassName,
112 long entryClassPK, String title, String link, Date updated,
113 String summary, double score, String format) {
114
115 addSearchResult(
116 root, groupId, scopeGroupId, entryClassName, entryClassPK, title,
117 link, updated, summary, new String[0], 0, score, format);
118 }
119
120 protected void addSearchResult(
121 Element root, long groupId, long scopeGroupId, String entryClassName,
122 long entryClassPK, String title, String link, Date updated,
123 String summary, String[] tags, double ratings, double score,
124 String format) {
125
126 if (format.equals("rss")) {
127 addSearchResultRSS(
128 root, groupId, scopeGroupId, entryClassName, entryClassPK,
129 title, link, updated, summary, tags, ratings, score);
130 }
131 else {
132 addSearchResultAtom(
133 root, groupId, scopeGroupId, entryClassName, entryClassPK,
134 title, link, updated, summary, tags, ratings, score);
135 }
136 }
137
138 protected void addSearchResultAtom(
139 Element root, long groupId, long scopeGroupId, String entryClassName,
140 long entryClassPK, String title, String link, Date updated,
141 String summary, String[] tags, double ratings, double score) {
142
143
144
145 Element entry = OpenSearchUtil.addElement(
146 root, "entry", OpenSearchUtil.DEFAULT_NAMESPACE);
147
148
149
150 OpenSearchUtil.addElement(
151 entry, "groupId", OpenSearchUtil.LIFERAY_NAMESPACE, groupId);
152
153
154
155 OpenSearchUtil.addElement(
156 entry, "scopeGroupId", OpenSearchUtil.LIFERAY_NAMESPACE,
157 scopeGroupId);
158
159
160
161 OpenSearchUtil.addElement(
162 entry, "entryClassName", OpenSearchUtil.LIFERAY_NAMESPACE,
163 entryClassName);
164
165
166
167 OpenSearchUtil.addElement(
168 entry, "entryClassPK", OpenSearchUtil.LIFERAY_NAMESPACE,
169 entryClassPK);
170
171
172
173 OpenSearchUtil.addElement(
174 entry, "title", OpenSearchUtil.DEFAULT_NAMESPACE, title);
175
176
177
178 Element entryLink = OpenSearchUtil.addElement(
179 entry, "link", OpenSearchUtil.DEFAULT_NAMESPACE);
180
181 entryLink.addAttribute("href", link);
182
183
184
185 OpenSearchUtil.addElement(
186 entry, "id", OpenSearchUtil.DEFAULT_NAMESPACE,
187 "urn:uuid:" + PortalUUIDUtil.generate());
188
189
190
191 OpenSearchUtil.addElement(
192 entry, "updated", OpenSearchUtil.DEFAULT_NAMESPACE, updated);
193
194
195
196 OpenSearchUtil.addElement(
197 entry, "summary", OpenSearchUtil.DEFAULT_NAMESPACE, summary);
198
199
200
201 OpenSearchUtil.addElement(
202 entry, "tags", OpenSearchUtil.DEFAULT_NAMESPACE,
203 StringUtil.merge(tags));
204
205
206
207 OpenSearchUtil.addElement(
208 entry, "ratings", OpenSearchUtil.DEFAULT_NAMESPACE, ratings);
209
210
211
212 OpenSearchUtil.addElement(
213 entry, "score", OpenSearchUtil.RELEVANCE_NAMESPACE, score);
214 }
215
216 protected void addSearchResultRSS(
217 Element root, long groupId, long scopeGroupId, String entryClassName,
218 long entryClassPK, String title, String link, Date updated,
219 String summary, String[] tags, double ratings, double score) {
220
221
222
223 Element item = root.addElement("item");
224
225
226
227 OpenSearchUtil.addElement(
228 item, "groupId", OpenSearchUtil.LIFERAY_NAMESPACE, groupId);
229
230
231
232 OpenSearchUtil.addElement(
233 item, "scopeGroupId", OpenSearchUtil.LIFERAY_NAMESPACE,
234 scopeGroupId);
235
236
237
238 OpenSearchUtil.addElement(
239 item, "entryClassName", OpenSearchUtil.LIFERAY_NAMESPACE,
240 entryClassName);
241
242
243
244 OpenSearchUtil.addElement(
245 item, "entryClassPK", OpenSearchUtil.LIFERAY_NAMESPACE,
246 entryClassPK);
247
248
249
250 OpenSearchUtil.addElement(
251 item, "title", OpenSearchUtil.NO_NAMESPACE, title);
252
253
254
255 OpenSearchUtil.addElement(
256 item, "link", OpenSearchUtil.NO_NAMESPACE, link);
257
258
259
260 OpenSearchUtil.addElement(
261 item, "description", OpenSearchUtil.NO_NAMESPACE, summary);
262
263
264
265 OpenSearchUtil.addElement(
266 item, "tags", OpenSearchUtil.NO_NAMESPACE, StringUtil.merge(tags));
267
268
269
270 OpenSearchUtil.addElement(
271 item, "ratings", OpenSearchUtil.NO_NAMESPACE, ratings);
272
273
274
275 OpenSearchUtil.addElement(
276 item, "score", OpenSearchUtil.RELEVANCE_NAMESPACE, score);
277 }
278
279
282 @Deprecated
283 protected Object[] addSearchResults(
284 String keywords, int startPage, int itemsPerPage, int total, int start,
285 String title, String searchPath, String format,
286 ThemeDisplay themeDisplay) {
287
288 return addSearchResults(
289 new String[0], keywords, startPage, itemsPerPage, total, start,
290 title, searchPath, format, themeDisplay);
291 }
292
293 protected Object[] addSearchResults(
294 String[] queryTerms, String keywords, int startPage, int itemsPerPage,
295 int total, int start, String title, String searchPath, String format,
296 ThemeDisplay themeDisplay) {
297
298 int totalPages = 0;
299
300 if ((total % itemsPerPage) == 0) {
301 totalPages = total / itemsPerPage;
302 }
303 else {
304 totalPages = (total / itemsPerPage) + 1;
305 }
306
307 int previousPage = startPage - 1;
308 int nextPage = startPage + 1;
309
310 Document doc = SAXReaderUtil.createDocument();
311
312 if (format.equals("rss")) {
313 return addSearchResultsRSS(
314 doc, queryTerms, keywords, startPage, itemsPerPage, total,
315 start, totalPages, previousPage, nextPage, title, searchPath,
316 themeDisplay);
317 }
318 else {
319 return addSearchResultsAtom(
320 doc, queryTerms, keywords, startPage, itemsPerPage, total,
321 start, totalPages, previousPage, nextPage, title, searchPath,
322 themeDisplay);
323 }
324 }
325
326 protected Object[] addSearchResultsAtom(
327 Document doc, String[] queryTerms, String keywords, int startPage,
328 int itemsPerPage, int total, int start, int totalPages,
329 int previousPage, int nextPage, String title, String searchPath,
330 ThemeDisplay themeDisplay) {
331
332
333
334 Element root = doc.addElement("feed");
335
336 root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.DEFAULT_NAMESPACE));
337 root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.OS_NAMESPACE));
338 root.add(
339 OpenSearchUtil.getNamespace(OpenSearchUtil.RELEVANCE_NAMESPACE));
340
341
342
343 OpenSearchUtil.addElement(
344 root, "title", OpenSearchUtil.DEFAULT_NAMESPACE, title);
345
346
347
348 OpenSearchUtil.addElement(
349 root, "updated", OpenSearchUtil.DEFAULT_NAMESPACE, new Date());
350
351
352
353 Element author = OpenSearchUtil.addElement(
354 root, "author", OpenSearchUtil.DEFAULT_NAMESPACE);
355
356
357
358 OpenSearchUtil.addElement(
359 author, "name", OpenSearchUtil.DEFAULT_NAMESPACE,
360 themeDisplay.getUserId());
361
362
363
364 OpenSearchUtil.addElement(
365 root, "id", OpenSearchUtil.DEFAULT_NAMESPACE,
366 "urn:uuid:" + PortalUUIDUtil.generate());
367
368
369
370 OpenSearchUtil.addElement(
371 root, "queryTerms", OpenSearchUtil.DEFAULT_NAMESPACE,
372 StringUtil.merge(queryTerms, StringPool.COMMA_AND_SPACE));
373
374
375
376 OpenSearchUtil.addElement(
377 root, "totalResults", OpenSearchUtil.OS_NAMESPACE, total);
378
379
380
381 OpenSearchUtil.addElement(
382 root, "startIndex", OpenSearchUtil.OS_NAMESPACE, start + 1);
383
384
385
386 OpenSearchUtil.addElement(
387 root, "itemsPerPage", OpenSearchUtil.OS_NAMESPACE, itemsPerPage);
388
389
390
391 Element query = OpenSearchUtil.addElement(
392 root, "Query", OpenSearchUtil.OS_NAMESPACE);
393
394 query.addAttribute("role", "request");
395 query.addAttribute("searchTerms", keywords);
396 query.addAttribute("startPage", String.valueOf(startPage));
397
398
399
400 String searchURL = themeDisplay.getURLPortal() + searchPath;
401
402 OpenSearchUtil.addLink(
403 root, searchURL, "self", keywords, startPage, itemsPerPage);
404 OpenSearchUtil.addLink(
405 root, searchURL, "first", keywords, 1, itemsPerPage);
406
407 if (previousPage > 0) {
408 OpenSearchUtil.addLink(
409 root, searchURL, "previous", keywords, previousPage,
410 itemsPerPage);
411 }
412
413 if (nextPage <= totalPages) {
414 OpenSearchUtil.addLink(
415 root, searchURL, "next", keywords, nextPage, itemsPerPage);
416 }
417
418 OpenSearchUtil.addLink(
419 root, searchURL, "last", keywords, totalPages, itemsPerPage);
420
421 Element link = OpenSearchUtil.addElement(
422 root, "link", OpenSearchUtil.DEFAULT_NAMESPACE);
423
424 link.addAttribute("rel", "search");
425 link.addAttribute("href", searchPath + "_description.xml");
426 link.addAttribute("type", "application/opensearchdescription+xml");
427
428 return new Object[] {doc, root};
429 }
430
431 protected Object[] addSearchResultsRSS(
432 Document doc, String[] queryTerms, String keywords, int startPage,
433 int itemsPerPage, int total, int start, int totalPages,
434 int previousPage, int nextPage, String title, String searchPath,
435 ThemeDisplay themeDisplay) {
436
437
438
439 Element root = doc.addElement("rss");
440
441 root.addAttribute("version", "2.0");
442 root.add(
443 SAXReaderUtil.createNamespace(
444 "atom", "http:
445 root.add(OpenSearchUtil.getNamespace(OpenSearchUtil.OS_NAMESPACE));
446 root.add(
447 OpenSearchUtil.getNamespace(OpenSearchUtil.RELEVANCE_NAMESPACE));
448
449
450
451 Element channel = root.addElement("channel");
452
453
454
455 OpenSearchUtil.addElement(
456 channel, "title", OpenSearchUtil.NO_NAMESPACE, title);
457
458
459
460 OpenSearchUtil.addElement(
461 channel, "link", OpenSearchUtil.NO_NAMESPACE,
462 themeDisplay.getURLPortal() + searchPath);
463
464
465
466 OpenSearchUtil.addElement(
467 channel, "description", OpenSearchUtil.NO_NAMESPACE, title);
468
469
470
471 OpenSearchUtil.addElement(
472 channel, "queryTerms", OpenSearchUtil.NO_NAMESPACE,
473 StringUtil.merge(queryTerms, StringPool.COMMA_AND_SPACE));
474
475
476
477 OpenSearchUtil.addElement(
478 channel, "totalResults", OpenSearchUtil.OS_NAMESPACE, total);
479
480
481
482 OpenSearchUtil.addElement(
483 channel, "startIndex", OpenSearchUtil.OS_NAMESPACE, start + 1);
484
485
486
487 OpenSearchUtil.addElement(
488 channel, "itemsPerPage", OpenSearchUtil.OS_NAMESPACE, itemsPerPage);
489
490
491
492 Element query = OpenSearchUtil.addElement(
493 channel, "Query", OpenSearchUtil.OS_NAMESPACE);
494
495 query.addAttribute("role", "request");
496 query.addAttribute("searchTerms", keywords);
497 query.addAttribute("startPage", String.valueOf(startPage));
498
499 return new Object[] {doc, channel};
500 }
501
502 protected PortletURL getPortletURL(
503 HttpServletRequest request, String portletId)
504 throws Exception {
505
506 return getPortletURL(request, portletId, 0);
507 }
508
509 protected PortletURL getPortletURL(
510 HttpServletRequest request, String portletId, long scopeGroupId)
511 throws Exception {
512
513 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
514
515 long layoutGroupId = scopeGroupId;
516
517 if (layout != null) {
518 layoutGroupId = layout.getGroupId();
519 }
520
521 long plid = LayoutServiceUtil.getDefaultPlid(
522 layoutGroupId, scopeGroupId, false, portletId);
523
524 if (plid == 0) {
525 plid = LayoutServiceUtil.getDefaultPlid(
526 layoutGroupId, scopeGroupId, true, portletId);
527 }
528
529 if (plid == 0) {
530 if (layout != null) {
531 plid = layout.getPlid();
532 }
533 }
534
535 PortletURL portletURL = PortletURLFactoryUtil.create(
536 request, portletId, plid, PortletRequest.RENDER_PHASE);
537
538 portletURL.setPortletMode(PortletMode.VIEW);
539 portletURL.setWindowState(WindowState.MAXIMIZED);
540
541 return portletURL;
542 }
543
544 private final boolean _enabled;
545
546 }