1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.wcm.webui.search;
18
19 import java.text.DateFormat;
20 import java.text.Normalizer;
21 import java.text.SimpleDateFormat;
22 import java.util.ArrayList;
23 import java.util.Calendar;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.MissingResourceException;
27 import java.util.ResourceBundle;
28 import java.util.Set;
29
30 import javax.jcr.Node;
31 import javax.jcr.Session;
32 import javax.jcr.Value;
33 import javax.portlet.PortletPreferences;
34 import javax.portlet.PortletRequest;
35
36 import org.exoplatform.commons.utils.ISO8601;
37 import org.apache.commons.lang.StringUtils;
38 import org.exoplatform.commons.utils.ObjectPageList;
39 import org.exoplatform.commons.utils.PageList;
40 import org.exoplatform.portal.application.PortalRequestContext;
41 import org.exoplatform.portal.mop.SiteType;
42 import org.exoplatform.portal.webui.container.UIContainer;
43 import org.exoplatform.portal.webui.util.Util;
44 import org.exoplatform.resolver.ResourceResolver;
45 import org.exoplatform.services.cms.templates.TemplateService;
46 import org.exoplatform.services.wcm.core.NodetypeConstant;
47 import org.exoplatform.services.wcm.portal.LivePortalManagerService;
48 import org.exoplatform.services.wcm.publication.WCMComposer;
49 import org.exoplatform.services.wcm.search.QueryCriteria;
50 import org.exoplatform.services.wcm.search.ResultNode;
51 import org.exoplatform.services.wcm.search.SiteSearchService;
52 import org.exoplatform.services.wcm.search.base.AbstractPageList;
53 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
54 import org.exoplatform.wcm.webui.Utils;
55 import org.exoplatform.wcm.webui.paginator.UICustomizeablePaginator;
56 import org.exoplatform.web.application.ApplicationMessage;
57 import org.exoplatform.web.url.navigation.NavigationResource;
58 import org.exoplatform.web.url.navigation.NodeURL;
59 import org.exoplatform.webui.application.WebuiRequestContext;
60 import org.exoplatform.webui.application.portlet.PortletRequestContext;
61 import org.exoplatform.webui.config.annotation.ComponentConfig;
62 import org.exoplatform.webui.config.annotation.ComponentConfigs;
63 import org.exoplatform.webui.config.annotation.EventConfig;
64 import org.exoplatform.webui.core.UIApplication;
65 import org.exoplatform.webui.core.lifecycle.Lifecycle;
66 import org.exoplatform.webui.form.UIFormHiddenInput;
67 import org.exoplatform.webui.form.UIFormRadioBoxInput;
68
69
70
71
72
73 @SuppressWarnings("deprecation")
74 @ComponentConfigs( {
75 @ComponentConfig(lifecycle = Lifecycle.class),
76 @ComponentConfig(type = UICustomizeablePaginator.class,
77 events = @EventConfig(listeners = UICustomizeablePaginator.ShowPageActionListener.class)) })
78 public class UISearchResult extends UIContainer {
79
80
81 private String templatePath;
82
83
84 private ResourceResolver resourceResolver;
85
86
87 private UICustomizeablePaginator uiPaginator;
88
89
90 private String keyword;
91
92
93 private String resultType;
94
95
96 private String suggestion;
97
98
99 private String suggestionURL;
100
101
102 private String pageMode;
103
104
105 private SimpleDateFormat dateFormatter = new SimpleDateFormat(ISO8601.SIMPLE_DATETIME_FORMAT);
106
107
108 private float searchTime;
109
110
111 private List<ResultNode> moreListResult;
112
113
114 private Set<Integer> morePageSet;
115
116
117 public final static String PARAMETER_REGX = "(portal=.*)&(keyword=.*)";
118
119
120 public final static String RESULT_NOT_FOUND = "UISearchResult.msg.result-not-found";
121
122
123
124
125
126
127
128
129 public void init(String templatePath, ResourceResolver resourceResolver) throws Exception {
130 PortletRequestContext portletRequestContext = (PortletRequestContext) WebuiRequestContext.getCurrentInstance();
131 PortletPreferences portletPreferences = portletRequestContext.getRequest().getPreferences();
132 String paginatorTemplatePath = portletPreferences.getValue(UIWCMSearchPortlet.SEARCH_PAGINATOR_TEMPLATE_PATH,
133 null);
134 this.pageMode = portletPreferences.getValue(UIWCMSearchPortlet.PAGE_MODE, SiteSearchService.PAGE_MODE_NONE);
135 this.templatePath = templatePath;
136 this.resourceResolver = resourceResolver;
137 uiPaginator = addChild(UICustomizeablePaginator.class, null, null);
138 uiPaginator.setTemplatePath(paginatorTemplatePath);
139 uiPaginator.setResourceResolver(resourceResolver);
140 uiPaginator.setPageMode(pageMode);
141 clearResult();
142 }
143
144
145
146
147
148
149
150 public void processRender(WebuiRequestContext context) throws Exception {
151 PortletRequestContext porletRequestContext = (PortletRequestContext) context;
152 PortletPreferences portletPreferences = porletRequestContext.getRequest().getPreferences();
153 if (resultType == null || resultType.trim().length() == 0) {
154 resultType = "Document";
155 }
156 PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
157 String portal = portalRequestContext.getRequestParameter("portal");
158 String keyword = portalRequestContext.getRequestParameter("keyword");
159 if ((portal != null) && (keyword != null) && (keyword.length() > 0)) {
160 UISearchPageLayout uiSearchPageContainer = getAncestorOfType(UISearchPageLayout.class);
161 UISearchForm searchForm = uiSearchPageContainer.getChild(UISearchForm.class);
162
163
164 searchForm.getUIStringInput(UISearchForm.KEYWORD_INPUT).setValue(keyword);
165 if (searchForm.getUIFormSelectBox(UISearchForm.PORTALS_SELECTOR).getValue() != null) {
166 portal = searchForm.getUIFormSelectBox(UISearchForm.PORTALS_SELECTOR).getValue();
167 }
168 if (searchForm.getUIStringInput(UISearchForm.KEYWORD_INPUT).getValue() != null) {
169 keyword = searchForm.getUIStringInput(UISearchForm.KEYWORD_INPUT).getValue();
170 }
171 setKeyword(keyword);
172 keyword = Normalizer.normalize(keyword, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
173
174 SiteSearchService siteSearchService = getApplicationComponent(SiteSearchService.class);
175 QueryCriteria queryCriteria = new QueryCriteria();
176
177 UIFormRadioBoxInput searchOption = searchForm.getUIFormRadioBoxInput(UISearchForm.SEARCH_OPTION);
178 boolean isSearchDocument = (searchOption.getValue().equals(UISearchForm.DOCUMENT_CHECKING));
179 boolean isWebPage = (searchOption.getValue().equals(UISearchForm.PAGE_CHECKING));
180
181 List<String> documentNodeTypes = new ArrayList<String>();
182 if (isSearchDocument) {
183 TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
184 documentNodeTypes = templateService.getAllDocumentNodeTypes();
185 portal = Util.getPortalRequestContext().getPortalOwner();
186 resultType = "Document";
187 } else {
188 documentNodeTypes.add("gtn:language");
189 documentNodeTypes.add("exo:pageMetadata");
190 queryCriteria.setFulltextSearchProperty(new String[] {"exo:metaKeywords", "exo:metaDescription", "gtn:name"});
191 resultType = "Page";
192 }
193
194 String pageMode = portletPreferences.getValue(UIWCMSearchPortlet.PAGE_MODE, SiteSearchService.PAGE_MODE_NONE);
195
196 queryCriteria.setContentTypes(documentNodeTypes.toArray(new String[documentNodeTypes.size()]));
197 queryCriteria.setSiteName(portal);
198 queryCriteria.setKeyword(
199 org.exoplatform.services.cms.impl.Utils.escapeIllegalCharacterInQuery(keyword).toLowerCase());
200 queryCriteria.setSearchWebpage(isWebPage);
201 queryCriteria.setSearchDocument(isSearchDocument);
202 queryCriteria.setSearchWebContent(isSearchDocument);
203 queryCriteria.setPageMode(pageMode);
204
205 queryCriteria.setLiveMode(WCMComposer.MODE_LIVE.equals(Utils.getCurrentMode()));
206 queryCriteria.setSortBy(this.getSortField());
207 queryCriteria.setOrderBy(this.getOrderType());
208 int itemsPerPage = Integer.parseInt(portletPreferences.getValue(UIWCMSearchPortlet.ITEMS_PER_PAGE,
209 null));
210 try {
211 AbstractPageList<ResultNode> pageList = null;
212 if (isWebPage) {
213 pageList = siteSearchService.searchPageContents(WCMCoreUtils.getSystemSessionProvider(),
214 queryCriteria,
215 porletRequestContext.getLocale(),
216 itemsPerPage,
217 false);
218 } else {
219 pageList = siteSearchService.searchSiteContents(WCMCoreUtils.getUserSessionProvider(),
220 queryCriteria,
221 porletRequestContext.getLocale(),
222 itemsPerPage,
223 false);
224 }
225
226 setSearchTime(pageList.getQueryTime() / 1000);
227 setSuggestion(pageList.getSpellSuggestion());
228 if (pageList.getAvailable() <= 0) {
229 String suggestion = pageList.getSpellSuggestion();
230 setSuggestionURL(suggestion);
231 searchForm.setSubmitAction(suggestion);
232 }
233 setPageList(pageList);
234 } catch (Exception e) {
235 UIApplication uiApp = getAncestorOfType(UIApplication.class);
236 uiApp.addMessage(new ApplicationMessage(UISearchForm.MESSAGE_NOT_SUPPORT_KEYWORD,
237 null,
238 ApplicationMessage.WARNING));
239 }
240 }
241 super.processRender(context);
242 }
243
244
245
246
247
248
249 @SuppressWarnings("unchecked")
250 public void setPageList(PageList dataPageList) {
251 uiPaginator.setPageList(dataPageList);
252 moreListResult = new ArrayList<ResultNode>();
253 morePageSet = new HashSet<Integer>();
254 }
255
256
257
258
259
260
261 public int getTotalItem() {
262 return uiPaginator.getPageList().getAvailable();
263 }
264
265
266
267
268
269
270 public int getItemsPerPage() {
271 return uiPaginator.getPageList().getPageSize();
272 }
273
274
275
276
277
278
279 public int getCurrentPage() {
280 return uiPaginator.getCurrentPage();
281 }
282
283
284
285
286
287 public String getPageMode() {
288 return pageMode;
289 }
290
291
292
293
294
295 public String getTemplate() {
296 return templatePath;
297 }
298
299
300
301
302
303
304
305
306
307 public ResourceResolver getTemplateResourceResolver(WebuiRequestContext context, String template) {
308 return resourceResolver;
309 }
310
311
312
313
314
315
316
317 @SuppressWarnings("unchecked")
318 public List getCurrentPageData() throws Exception {
319 return uiPaginator.getCurrentPageData();
320 }
321
322
323
324
325
326
327
328
329 public String getTitle(Node node) throws Exception {
330 if (UIWCMSearchPortlet.SEARCH_CONTENT_MODE.equals(this.getResultType())) {
331 return org.exoplatform.ecm.webui.utils.Utils.getTitle(node);
332 } else {
333 Session session = node.getSession();
334 Node mopLink = (Node) session.getItem(node.getPath() + "/mop:link");
335 if (mopLink != null && mopLink.hasProperty("mop:page")) {
336 String mopPageLink = mopLink.getProperty("mop:page").getValue().getString();
337 Node mopPage = (Node) session.getItem(mopPageLink);
338 if (mopPage != null && mopPage.hasProperty("gtn:name")) {
339 return mopPage.getProperty("gtn:name").getValue().getString();
340 } else {
341 return node.getName().replaceFirst("mop:", "");
342 }
343 } else {
344 return node.getName().replaceFirst("mop:", "");
345 }
346
347 }
348 }
349
350
351
352
353
354
355
356
357 public List<String> getURLs(Node node) throws Exception {
358 List<String> urls = new ArrayList<String>();
359 if (!node.hasProperty("publication:navigationNodeURIs")) {
360 urls.add(getURL(node));
361 } else {
362 for (Value value : node.getProperty("publication:navigationNodeURIs").getValues()) {
363 urls.add(value.getString());
364 }
365 }
366 return urls;
367 }
368
369
370
371
372
373
374
375 public String getPublishedNodeURI(String navNodeURI) {
376 PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
377 PortletRequest portletRequest = getPortletRequest();
378
379 StringBuffer baseURI = new StringBuffer();
380 baseURI.append(portletRequest.getScheme()).append("://").append(portletRequest.getServerName());
381 if (portletRequest.getServerPort() != 80) {
382 baseURI.append(":").append(String.format("%s", portletRequest.getServerPort()));
383 }
384 if (navNodeURI.startsWith(baseURI.toString()))
385 return navNodeURI;
386
387 NodeURL nodeURL = portalRequestContext.createURL(NodeURL.TYPE);
388 NavigationResource resource = new NavigationResource(portalRequestContext.getSiteType(),
389 portalRequestContext.getSiteName(),
390 navNodeURI);
391 nodeURL.setResource(resource);
392 return baseURI + nodeURL.toString();
393 }
394
395
396
397
398
399
400
401
402 public String getURL(Node node) throws Exception {
403 PortletRequest portletRequest = getPortletRequest();
404 PortletPreferences portletPreferences = portletRequest.getPreferences();
405 String repository = WCMCoreUtils.getRepository().getConfiguration().getName();
406 String workspace = portletPreferences.getValue(UIWCMSearchPortlet.WORKSPACE, null);
407 String basePath = portletPreferences.getValue(UIWCMSearchPortlet.BASE_PATH, null);
408 String detailParameterName = portletPreferences.getValue(UIWCMSearchPortlet.DETAIL_PARAMETER_NAME, null);
409
410 StringBuffer path = new StringBuffer();
411 path.append("/").append(repository).append("/").append(workspace);
412 NodeURL nodeURL = Util.getPortalRequestContext().createURL(NodeURL.TYPE);
413 NavigationResource resource = new NavigationResource(SiteType.PORTAL,
414 Util.getPortalRequestContext()
415 .getPortalOwner(), basePath);
416 nodeURL.setResource(resource);
417 if (node.isNodeType("nt:frozenNode")) {
418 String uuid = node.getProperty("jcr:frozenUuid").getString();
419 Node originalNode = node.getSession().getNodeByUUID(uuid);
420 path.append(originalNode.getPath());
421 nodeURL.setQueryParameterValue("version", node.getParent().getName());
422 } else {
423 path.append(node.getPath());
424 }
425
426 nodeURL.setQueryParameterValue(detailParameterName, path.toString());
427 nodeURL.setSchemeUse(true);
428 return nodeURL.toString();
429 }
430
431 private PortletRequest getPortletRequest() {
432 PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
433 return portletRequestContext.getRequest();
434 }
435
436
437
438
439
440
441
442
443 public String getCreatedDate(Node node) throws Exception {
444 if (node.hasProperty("exo:dateCreated")) {
445 Calendar calendar = node.getProperty("exo:dateCreated").getValue().getDate();
446 return dateFormatter.format(calendar.getTime());
447 }
448 return null;
449 }
450
451
452
453
454
455
456
457
458 private String getModifiedDate(Node node) throws Exception {
459 Calendar calendar = node.hasProperty(NodetypeConstant.EXO_LAST_MODIFIED_DATE) ?
460 node.getProperty(NodetypeConstant.EXO_LAST_MODIFIED_DATE).getDate() :
461 node.getProperty(NodetypeConstant.EXO_DATE_CREATED).getDate();
462 DateFormat simpleDateFormat = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.FULL, SimpleDateFormat.SHORT);
463 return simpleDateFormat.format(calendar.getTime());
464 }
465
466
467
468
469
470
471
472 public boolean isShowPaginator() throws Exception {
473 PortletPreferences portletPreferences = ((PortletRequestContext) WebuiRequestContext.getCurrentInstance()).getRequest()
474 .getPreferences();
475 String itemsPerPage = portletPreferences.getValue(UIWCMSearchPortlet.ITEMS_PER_PAGE, null);
476 int totalItems = uiPaginator.getTotalItems();
477 if (totalItems > Integer.parseInt(itemsPerPage)) {
478 return true;
479 }
480 return false;
481 }
482
483
484
485
486
487
488 public float getSearchTime() {
489 return searchTime;
490 }
491
492
493
494
495
496
497 public void setSearchTime(float searchTime) {
498 this.searchTime = searchTime;
499 }
500
501
502
503
504
505
506 public String getSuggestion() {
507 return suggestion;
508 }
509
510
511
512
513
514
515 public void setSuggestion(String suggestion) {
516 this.suggestion = suggestion;
517 }
518
519
520
521
522
523
524 public String getSuggestionURL() {
525 return suggestionURL;
526 }
527
528
529
530
531
532
533 public void setSuggestionURL(String suggestionURL) {
534 this.suggestionURL = suggestionURL;
535 }
536
537
538
539
540
541
542 public String getKeyword() {
543 return this.keyword;
544 }
545
546
547
548
549
550
551 public void setKeyword(String keyword) {
552 this.keyword = keyword;
553 }
554
555
556
557
558
559
560 public String getResultType() {
561 return this.resultType;
562 }
563
564
565
566
567
568
569 public void setResultType(String resultType) {
570 this.resultType = resultType;
571 }
572
573
574
575
576
577
578 public int getNumberOfPage() {
579 return uiPaginator.getPageList().getAvailablePage();
580 }
581
582
583
584
585 @SuppressWarnings("unchecked")
586 public void clearResult() {
587 moreListResult = new ArrayList<ResultNode>();
588 morePageSet = new HashSet<Integer>();
589 PortletPreferences portletPreferences = ((PortletRequestContext) WebuiRequestContext.getCurrentInstance()).getRequest()
590 .getPreferences();
591 String itemsPerPage = portletPreferences.getValue(UIWCMSearchPortlet.ITEMS_PER_PAGE, null);
592 setPageList(new ObjectPageList(new ArrayList<ResultNode>(), Integer.parseInt(itemsPerPage)));
593 }
594
595
596
597
598
599
600 public List<ResultNode> getRealCurrentPageData() throws Exception {
601 int currentPage = getCurrentPage();
602 if (SiteSearchService.PAGE_MODE_MORE.equals(pageMode)) {
603 if (!morePageSet.contains(currentPage)) {
604 morePageSet.add(currentPage);
605 moreListResult.addAll(getCurrentPageData());
606 }
607 }
608 return SiteSearchService.PAGE_MODE_MORE.equals(pageMode) ? moreListResult : getCurrentPageData();
609 }
610
611
612
613
614
615
616
617
618 private String getDetail(ResultNode resultNode) throws Exception {
619 Node realNode = org.exoplatform.wcm.webui.Utils.getRealNode(resultNode.getNode());
620 String resultType = this.getResultType();
621 if (UIWCMSearchPortlet.SEARCH_CONTENT_MODE.equals(resultType)) {
622 return WCMCoreUtils.getService(LivePortalManagerService.class).getLivePortalByChild(realNode).getName()
623 .concat(org.exoplatform.services.cms.impl.Utils.fileSize(realNode))
624 .concat(" - ")
625 .concat(getModifiedDate(realNode));
626 } else {
627 return StringUtils.substringBefore(StringUtils.substringAfter(realNode.getPath(),
628 SiteSearchService.PATH_PORTAL_SITES.concat("/mop:")),"/")
629 .concat(" - ")
630 .concat(resultNode.getUserNavigationURI());
631 }
632 }
633
634
635
636
637
638
639
640 private String getLabel(String key) {
641 try {
642 ResourceBundle rs = WebuiRequestContext.getCurrentInstance().getApplicationResourceBundle();
643 return rs.getString(key);
644 } catch (MissingResourceException e) {
645 return key;
646 }
647 }
648
649
650
651
652
653
654
655 private String getOrderType() throws Exception {
656 UISearchForm uiSearchForm = this.getParent().findFirstComponentOfType(UISearchForm.class);
657 String orderType = ((UIFormHiddenInput)uiSearchForm.getUIInput(UISearchForm.ORDER_TYPE_HIDDEN_INPUT)).getValue();
658 return StringUtils.isEmpty(orderType) ? "asc" : orderType;
659 }
660
661
662
663
664
665
666 private String getSortField() {
667 UISearchForm uiSearchForm = this.getParent().findFirstComponentOfType(UISearchForm.class);
668 String sortField = ((UIFormHiddenInput)uiSearchForm.getUIInput(UISearchForm.SORT_FIELD_HIDDEN_INPUT)).getValue();
669 return StringUtils.isEmpty(sortField) ? "relevancy" : sortField;
670 }
671 }