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