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