/*
* Copyright (C) 2003-2008 eXo Platform SAS. This program is free software; you
* can redistribute it and/or modify it under the terms of the GNU Affero
* General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version. This program
* is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details. You
* should have received a copy of the GNU General Public License along with this
* program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.wcm.webui.search;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.List;
import javax.portlet.PortletPreferences;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.Query;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.resolver.ResourceResolver;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.wcm.publication.WCMComposer;
import org.exoplatform.services.wcm.search.QueryCriteria;
import org.exoplatform.services.wcm.search.ResultNode;
import org.exoplatform.services.wcm.search.SiteSearchService;
import org.exoplatform.services.wcm.search.base.AbstractPageList;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.exoplatform.wcm.webui.Utils;
import org.exoplatform.web.application.ApplicationMessage;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.application.portlet.PortletRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIApplication;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.core.model.SelectItemOption;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.EventListener;
import org.exoplatform.webui.form.UIForm;
import org.exoplatform.webui.form.UIFormHiddenInput;
import org.exoplatform.webui.form.UIFormRadioBoxInput;
import org.exoplatform.webui.form.UIFormSelectBox;
import org.exoplatform.webui.form.UIFormStringInput;
/*
* Created by The eXo Platform SAS Author : Anh Do Ngoc anh.do@exoplatform.com
* Oct 31, 2008
*/
@ComponentConfig(lifecycle = UIFormLifecycle.class,
events = {
@EventConfig(listeners = UISearchForm.SearchActionListener.class) })
public class UISearchForm extends UIForm {
/** The template path. */
private String templatePath;
/** The resource resolver. */
private ResourceResolver resourceResolver;
/** The Constant KEYWORD_INPUT. */
public static final String KEYWORD_INPUT = "keywordInput";
/** The Constant SEARCH_OPTION. */
public static final String SEARCH_OPTION = "searchOption";
/** The Constant DOCUMENT_CHECKING. */
public static final String DOCUMENT_CHECKING = "documentCheckBox";
/** The Constant PAGE_CHECKING. */
public static final String PAGE_CHECKING = "pageCheckBox";
/** The Constant PORTALS_SELECTOR. */
public static final String PORTALS_SELECTOR = "portalSelector";
/** The Constant ALL_OPTION. */
public static final String ALL_OPTION = "all";
/** The Constant SORT_FIELD_HIDDEN_INPUT */
public static final String SORT_FIELD_HIDDEN_INPUT = "sortHiddenInputField";
/** The Constant ORDER_TYPE_HIDDEN_INPUT */
public static final String ORDER_TYPE_HIDDEN_INPUT = "orderTypeHiddenInputField";
/** The Constant MESSAGE_NOT_CHECKED_TYPE_SEARCH. */
public static final String MESSAGE_NOT_CHECKED_TYPE_SEARCH = "UISearchForm.message.not-checked";
/** The Constant MESSAGE_NOT_SUPPORT_KEYWORD. */
public static final String MESSAGE_NOT_SUPPORT_KEYWORD = "UISearchForm.message.keyword-not-support";
/** The Constant MESSAGE_NOT_EMPTY_KEYWORD. */
public static final String MESSAGE_NOT_EMPTY_KEYWORD = "UISearchForm.message.keyword-not-empty";
/**
* Instantiates a new uI search form.
*
* @throws Exception the exception
*/
@SuppressWarnings("unchecked")
public UISearchForm() throws Exception {
UIFormStringInput uiKeywordInput = new UIFormStringInput(KEYWORD_INPUT, KEYWORD_INPUT, null);
UIFormSelectBox uiPortalSelectBox = new UIFormSelectBox(PORTALS_SELECTOR,
PORTALS_SELECTOR,
getPortalList());
List<SelectItemOption<String>> searchOptionList = new ArrayList<SelectItemOption<String>>();
SelectItemOption<String> pageOption = new SelectItemOption<String>(PAGE_CHECKING, PAGE_CHECKING);
SelectItemOption<String> docOption = new SelectItemOption<String>(DOCUMENT_CHECKING, DOCUMENT_CHECKING);
searchOptionList.add(docOption);
searchOptionList.add(pageOption);
UIFormRadioBoxInput searchOptionRadioBox = new UIFormRadioBoxInput(SEARCH_OPTION, SEARCH_OPTION, searchOptionList);
searchOptionRadioBox.setDefaultValue(DOCUMENT_CHECKING);
searchOptionRadioBox.setValue(DOCUMENT_CHECKING);
addUIFormInput(uiKeywordInput);
addUIFormInput(uiPortalSelectBox);
addUIFormInput(searchOptionRadioBox);
// Hidden fields for storing order criteria from user
addUIFormInput(new UIFormHiddenInput(SORT_FIELD_HIDDEN_INPUT, SORT_FIELD_HIDDEN_INPUT, null));
addUIFormInput(new UIFormHiddenInput(ORDER_TYPE_HIDDEN_INPUT, ORDER_TYPE_HIDDEN_INPUT, null));
}
/**
* Inits the.
*
* @param templatePath the template path
* @param resourceResolver the resource resolver
*/
public void init(String templatePath, ResourceResolver resourceResolver) {
this.templatePath = templatePath;
this.resourceResolver = resourceResolver;
}
/*
* (non-Javadoc)
* @see org.exoplatform.webui.core.UIComponent#getTemplate()
*/
public String getTemplate() {
return templatePath;
}
public void setKeyword() {
PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
String keyword = portalRequestContext.getRequestParameter("keyword");
if (keyword != null && keyword.length() > 0) {
getUIStringInput(UISearchForm.KEYWORD_INPUT).setValue(keyword);
}
}
/*
* (non-Javadoc)
* @see
* org.exoplatform.webui.core.UIComponent#getTemplateResourceResolver(org.
* exoplatform.webui.application.WebuiRequestContext, java.lang.String)
*/
public ResourceResolver getTemplateResourceResolver(WebuiRequestContext context, String template) {
return resourceResolver;
}
/**
* Gets the portal list.
*
* @return the portal list
* @throws Exception the exception
*/
@SuppressWarnings("unchecked")
private List getPortalList() throws Exception {
List<SelectItemOption<String>> portals = new ArrayList<SelectItemOption<String>>();
DataStorage service = getApplicationComponent(DataStorage.class);
Query<PortalConfig> query = new Query<PortalConfig>(null, null, null, null, PortalConfig.class);
List<PortalConfig> list = service.find(query).getAll();
portals.add(new SelectItemOption<String>(ALL_OPTION, ALL_OPTION));
for (PortalConfig portalConfig : list) {
portals.add(new SelectItemOption<String>(portalConfig.getName(), portalConfig.getName()));
}
return portals;
}
/**
* The listener interface for receiving searchAction events. The class that is
* interested in processing a searchAction event implements this interface,
* and the object created with that class is registered with a component using
* the component's <code>addSearchActionListener</code> method. When
* the searchAction event occurs, that object's appropriate
* method is invoked.
*
*/
public static class SearchActionListener extends EventListener<UISearchForm> {
/*
* (non-Javadoc)
* @see
* org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui
* .event.Event)
*/
@SuppressWarnings({ "deprecation" })
public void execute(Event<UISearchForm> event) throws Exception {
UISearchForm uiSearchForm = event.getSource();
PortletRequestContext portletRequestContext = (PortletRequestContext) event.getRequestContext();
PortletPreferences portletPreferences = portletRequestContext.getRequest().getPreferences();
UIApplication uiApp = uiSearchForm.getAncestorOfType(UIApplication.class);
SiteSearchService siteSearchService = uiSearchForm.getApplicationComponent(SiteSearchService.class);
UISearchPageLayout uiSearchPageContainer = uiSearchForm.getParent();
UISearchResult uiSearchResult = uiSearchPageContainer.getChild(UISearchResult.class);
UIFormStringInput uiKeywordInput = uiSearchForm.getUIStringInput(UISearchForm.KEYWORD_INPUT);
UIFormSelectBox uiPortalSelectBox = uiSearchForm.getUIFormSelectBox(UISearchForm.PORTALS_SELECTOR);
String keyword = uiKeywordInput.getValue();
UIFormRadioBoxInput uiSearchOptionRadioBox = uiSearchForm.getUIFormRadioBoxInput(SEARCH_OPTION);
String searchOption = uiSearchOptionRadioBox.getValue();
String sortField = ((UIFormHiddenInput)uiSearchForm.getUIInput(UISearchForm.SORT_FIELD_HIDDEN_INPUT)).getValue();
String orderType = ((UIFormHiddenInput)uiSearchForm.getUIInput(UISearchForm.ORDER_TYPE_HIDDEN_INPUT)).getValue();
boolean pageChecked = false;
boolean documentChecked = false;
if (PAGE_CHECKING.equals(searchOption)) {
pageChecked = true;
} else if (DOCUMENT_CHECKING.equals(searchOption)) {
documentChecked = true;
}
uiSearchResult.clearResult();
uiSearchResult.setKeyword(keyword);
if (keyword == null || keyword.trim().length() == 0) {
uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_EMPTY_KEYWORD,
null,
ApplicationMessage.WARNING));
portletRequestContext.addUIComponentToUpdateByAjax(uiSearchResult);
return;
}
if (!pageChecked && !documentChecked) {
uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_CHECKED_TYPE_SEARCH,
null,
ApplicationMessage.WARNING));
return;
}
String resultType = null;
if (pageChecked) {
resultType = UIWCMSearchPortlet.SEARCH_PAGE_MODE;
} else {
resultType = UIWCMSearchPortlet.SEARCH_CONTENT_MODE;
}
String newKey = event.getRequestContext().getRequestParameter(OBJECTID);
if (newKey != null) {
keyword = newKey;
uiKeywordInput.setValue(newKey);
}
keyword = Normalizer.normalize(keyword, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
//keyword = keyword.replaceAll("'","''");
uiSearchResult.setResultType(resultType);
String selectedPortal = uiPortalSelectBox.getValue();
QueryCriteria queryCriteria = new QueryCriteria();
List<String> documentNodeTypes = new ArrayList<String>();
if (documentChecked) {
TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
documentNodeTypes = templateService.getAllDocumentNodeTypes();
selectedPortal = Util.getPortalRequestContext().getPortalOwner();
} else {
documentNodeTypes.add("gtn:language");
documentNodeTypes.add("exo:pageMetadata");
queryCriteria.setFulltextSearchProperty(new String[] {"exo:metaKeywords", "exo:metaDescription", "gtn:name"});
}
queryCriteria.setContentTypes(documentNodeTypes.toArray(new String[documentNodeTypes.size()]));
queryCriteria.setSiteName(selectedPortal);
queryCriteria.setKeyword(
org.exoplatform.services.cms.impl.Utils.escapeIllegalCharacterInQuery(keyword));
if (documentChecked) {
queryCriteria.setSearchDocument(true);
queryCriteria.setSearchWebContent(true);
} else {
queryCriteria.setSearchDocument(false);
queryCriteria.setSearchWebContent(false);
}
queryCriteria.setSearchWebpage(pageChecked);
queryCriteria.setLiveMode(WCMComposer.MODE_LIVE.equals(Utils.getCurrentMode()));
int itemsPerPage = Integer.parseInt(portletPreferences.getValue(UIWCMSearchPortlet.ITEMS_PER_PAGE,
null));
queryCriteria.setPageMode(portletPreferences.getValue(UIWCMSearchPortlet.PAGE_MODE, null));
queryCriteria.setSortBy(sortField);
queryCriteria.setOrderBy(orderType);
try {
AbstractPageList<ResultNode> pageList = null;
if (pageChecked) {
pageList = siteSearchService.searchPageContents(WCMCoreUtils.getSystemSessionProvider(),
queryCriteria,
itemsPerPage,
false);
} else {
pageList = siteSearchService.searchSiteContents(WCMCoreUtils.getUserSessionProvider(),
queryCriteria,
itemsPerPage,
false);
}
uiSearchResult.setPageList(pageList);
float timeSearch = pageList.getQueryTime() / 1000;
uiSearchResult.setSearchTime(timeSearch);
if (pageList.getAvailable() <= 0) {
String suggestion = pageList.getSpellSuggestion();
uiSearchResult.setSuggestion(suggestion);
uiSearchForm.setSubmitAction(suggestion);
}
portletRequestContext.addUIComponentToUpdateByAjax(uiSearchResult);
} catch (Exception e) {
uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_SUPPORT_KEYWORD,
null,
ApplicationMessage.WARNING));
return;
}
portletRequestContext.addUIComponentToUpdateByAjax(uiSearchPageContainer);
}
}
public UIFormRadioBoxInput getUIFormRadioBoxInput(String name)
{
return findComponentById(name);
}
}