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