View Javadoc
1   /*
2    * Copyright (C) 2003-2008 eXo Platform SAS. This program is free software; you
3    * can redistribute it and/or modify it under the terms of the GNU Affero
4    * General Public License as published by the Free Software Foundation; either
5    * version 3 of the License, or (at your option) any later version. This program
6    * is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7    * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8    * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
9    * should have received a copy of the GNU General Public License along with this
10   * program; if not, see<http://www.gnu.org/licenses/>.
11   */
12  package org.exoplatform.wcm.webui.search;
13  
14  import java.text.Normalizer;
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  import javax.portlet.PortletPreferences;
19  
20  import org.exoplatform.portal.application.PortalRequestContext;
21  import org.exoplatform.portal.config.DataStorage;
22  import org.exoplatform.portal.config.Query;
23  import org.exoplatform.portal.config.model.PortalConfig;
24  import org.exoplatform.portal.webui.util.Util;
25  import org.exoplatform.resolver.ResourceResolver;
26  import org.exoplatform.services.cms.templates.TemplateService;
27  import org.exoplatform.services.wcm.publication.WCMComposer;
28  import org.exoplatform.services.wcm.search.QueryCriteria;
29  import org.exoplatform.services.wcm.search.ResultNode;
30  import org.exoplatform.services.wcm.search.SiteSearchService;
31  import org.exoplatform.services.wcm.search.base.AbstractPageList;
32  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
33  import org.exoplatform.wcm.webui.Utils;
34  import org.exoplatform.web.application.ApplicationMessage;
35  import org.exoplatform.webui.application.WebuiRequestContext;
36  import org.exoplatform.webui.application.portlet.PortletRequestContext;
37  import org.exoplatform.webui.config.annotation.ComponentConfig;
38  import org.exoplatform.webui.config.annotation.EventConfig;
39  import org.exoplatform.webui.core.UIApplication;
40  import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
41  import org.exoplatform.webui.core.model.SelectItemOption;
42  import org.exoplatform.webui.event.Event;
43  import org.exoplatform.webui.event.EventListener;
44  import org.exoplatform.webui.form.UIForm;
45  import org.exoplatform.webui.form.UIFormHiddenInput;
46  import org.exoplatform.webui.form.UIFormRadioBoxInput;
47  import org.exoplatform.webui.form.UIFormSelectBox;
48  import org.exoplatform.webui.form.UIFormStringInput;
49  
50  /*
51   * Created by The eXo Platform SAS Author : Anh Do Ngoc anh.do@exoplatform.com
52   * Oct 31, 2008
53   */
54  @ComponentConfig(lifecycle = UIFormLifecycle.class,
55                   events = {
56    @EventConfig(listeners = UISearchForm.SearchActionListener.class) })
57  public class UISearchForm extends UIForm {
58  
59    /** The template path. */
60    private String             templatePath;
61  
62    /** The resource resolver. */
63    private ResourceResolver   resourceResolver;
64  
65    /** The Constant KEYWORD_INPUT. */
66    public static final String KEYWORD_INPUT                   = "keywordInput";
67  
68    /** The Constant SEARCH_OPTION. */
69    public static final String SEARCH_OPTION                   = "searchOption";
70    
71    /** The Constant DOCUMENT_CHECKING. */
72    public static final String DOCUMENT_CHECKING               = "documentCheckBox";
73  
74    /** The Constant PAGE_CHECKING. */
75    public static final String PAGE_CHECKING                   = "pageCheckBox";
76  
77    /** The Constant PORTALS_SELECTOR. */
78    public static final String PORTALS_SELECTOR                = "portalSelector";
79  
80    /** The Constant ALL_OPTION. */
81    public static final String ALL_OPTION                      = "all";
82  
83    /** The Constant SORT_FIELD_HIDDEN_INPUT */
84    public static final String SORT_FIELD_HIDDEN_INPUT = "sortHiddenInputField";
85  
86    /** The Constant ORDER_TYPE_HIDDEN_INPUT */
87    public static final String ORDER_TYPE_HIDDEN_INPUT = "orderTypeHiddenInputField";
88  
89    /** The Constant MESSAGE_NOT_CHECKED_TYPE_SEARCH. */
90    public static final String MESSAGE_NOT_CHECKED_TYPE_SEARCH = "UISearchForm.message.not-checked";
91  
92    /** The Constant MESSAGE_NOT_SUPPORT_KEYWORD. */
93    public static final String MESSAGE_NOT_SUPPORT_KEYWORD     = "UISearchForm.message.keyword-not-support";
94  
95    /** The Constant MESSAGE_NOT_EMPTY_KEYWORD. */
96    public static final String MESSAGE_NOT_EMPTY_KEYWORD       = "UISearchForm.message.keyword-not-empty";
97  
98    /**
99     * Instantiates a new uI search form.
100    *
101    * @throws Exception the exception
102    */
103   @SuppressWarnings("unchecked")
104   public UISearchForm() throws Exception {
105     UIFormStringInput uiKeywordInput = new UIFormStringInput(KEYWORD_INPUT, KEYWORD_INPUT, null);
106     UIFormSelectBox uiPortalSelectBox = new UIFormSelectBox(PORTALS_SELECTOR,
107                                                             PORTALS_SELECTOR,
108                                                             getPortalList());
109     List<SelectItemOption<String>> searchOptionList = new ArrayList<SelectItemOption<String>>();
110     SelectItemOption<String> pageOption = new SelectItemOption<String>(PAGE_CHECKING, PAGE_CHECKING);
111     SelectItemOption<String> docOption = new SelectItemOption<String>(DOCUMENT_CHECKING, DOCUMENT_CHECKING);
112     searchOptionList.add(docOption);
113     searchOptionList.add(pageOption);
114     UIFormRadioBoxInput searchOptionRadioBox = new UIFormRadioBoxInput(SEARCH_OPTION, SEARCH_OPTION, searchOptionList);
115     searchOptionRadioBox.setDefaultValue(DOCUMENT_CHECKING);
116     searchOptionRadioBox.setValue(DOCUMENT_CHECKING);
117     
118     addUIFormInput(uiKeywordInput);
119     addUIFormInput(uiPortalSelectBox);
120     addUIFormInput(searchOptionRadioBox);
121 
122     // Hidden fields for storing order criteria from user
123     addUIFormInput(new UIFormHiddenInput(SORT_FIELD_HIDDEN_INPUT, SORT_FIELD_HIDDEN_INPUT, null));
124     addUIFormInput(new UIFormHiddenInput(ORDER_TYPE_HIDDEN_INPUT, ORDER_TYPE_HIDDEN_INPUT, null));
125   }
126 
127   /**
128    * Inits the.
129    *
130    * @param templatePath the template path
131    * @param resourceResolver the resource resolver
132    */
133   public void init(String templatePath, ResourceResolver resourceResolver) {
134     this.templatePath = templatePath;
135     this.resourceResolver = resourceResolver;
136   }
137 
138   /*
139    * (non-Javadoc)
140    * @see org.exoplatform.webui.core.UIComponent#getTemplate()
141    */
142   public String getTemplate() {
143     return templatePath;
144   }
145 
146   public void setKeyword() {
147     PortalRequestContext portalRequestContext = Util.getPortalRequestContext();
148     String keyword = portalRequestContext.getRequestParameter("keyword");
149     if (keyword != null && keyword.length() > 0) {
150       getUIStringInput(UISearchForm.KEYWORD_INPUT).setValue(keyword);
151     }
152   }
153 
154   /*
155    * (non-Javadoc)
156    * @see
157    * org.exoplatform.webui.core.UIComponent#getTemplateResourceResolver(org.
158    * exoplatform.webui.application.WebuiRequestContext, java.lang.String)
159    */
160   public ResourceResolver getTemplateResourceResolver(WebuiRequestContext context, String template) {
161     return resourceResolver;
162   }
163 
164   /**
165    * Gets the portal list.
166    *
167    * @return the portal list
168    * @throws Exception the exception
169    */
170   @SuppressWarnings("unchecked")
171   private List getPortalList() throws Exception {
172     List<SelectItemOption<String>> portals = new ArrayList<SelectItemOption<String>>();
173     DataStorage service = getApplicationComponent(DataStorage.class);
174     Query<PortalConfig> query = new Query<PortalConfig>(null, null, null, null, PortalConfig.class);
175     List<PortalConfig> list = service.find(query).getAll();
176     portals.add(new SelectItemOption<String>(ALL_OPTION, ALL_OPTION));
177     for (PortalConfig portalConfig : list) {
178       portals.add(new SelectItemOption<String>(portalConfig.getName(), portalConfig.getName()));
179     }
180     return portals;
181   }
182 
183   /**
184    * The listener interface for receiving searchAction events. The class that is
185    * interested in processing a searchAction event implements this interface,
186    * and the object created with that class is registered with a component using
187    * the component's <code>addSearchActionListener</code> method. When
188    * the searchAction event occurs, that object's appropriate
189    * method is invoked.
190    *
191    */
192   public static class SearchActionListener extends EventListener<UISearchForm> {
193 
194     /*
195      * (non-Javadoc)
196      * @see
197      * org.exoplatform.webui.event.EventListener#execute(org.exoplatform.webui
198      * .event.Event)
199      */
200     @SuppressWarnings({ "deprecation" })
201     public void execute(Event<UISearchForm> event) throws Exception {
202       UISearchForm uiSearchForm = event.getSource();
203       PortletRequestContext portletRequestContext = (PortletRequestContext) event.getRequestContext();
204       PortletPreferences portletPreferences = portletRequestContext.getRequest().getPreferences();
205       UIApplication uiApp = uiSearchForm.getAncestorOfType(UIApplication.class);
206       SiteSearchService siteSearchService = uiSearchForm.getApplicationComponent(SiteSearchService.class);
207       UISearchPageLayout uiSearchPageContainer = uiSearchForm.getParent();
208       UISearchResult uiSearchResult = uiSearchPageContainer.getChild(UISearchResult.class);
209       UIFormStringInput uiKeywordInput = uiSearchForm.getUIStringInput(UISearchForm.KEYWORD_INPUT);
210       UIFormSelectBox uiPortalSelectBox = uiSearchForm.getUIFormSelectBox(UISearchForm.PORTALS_SELECTOR);
211       String keyword = uiKeywordInput.getValue();
212       UIFormRadioBoxInput uiSearchOptionRadioBox = uiSearchForm.getUIFormRadioBoxInput(SEARCH_OPTION);
213       String searchOption = uiSearchOptionRadioBox.getValue();
214       String sortField = ((UIFormHiddenInput)uiSearchForm.getUIInput(UISearchForm.SORT_FIELD_HIDDEN_INPUT)).getValue();
215       String orderType = ((UIFormHiddenInput)uiSearchForm.getUIInput(UISearchForm.ORDER_TYPE_HIDDEN_INPUT)).getValue();
216       boolean pageChecked = false;
217       boolean documentChecked = false;
218       if (PAGE_CHECKING.equals(searchOption)) {
219         pageChecked = true;
220       } else if (DOCUMENT_CHECKING.equals(searchOption)) {
221         documentChecked = true;
222       }
223       
224       uiSearchResult.clearResult();
225       uiSearchResult.setKeyword(keyword);
226       if (keyword == null || keyword.trim().length() == 0) {
227         uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_EMPTY_KEYWORD,
228                                                 null,
229                                                 ApplicationMessage.WARNING));
230         portletRequestContext.addUIComponentToUpdateByAjax(uiSearchResult);
231         return;
232       }
233       if (!pageChecked && !documentChecked) {
234         uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_CHECKED_TYPE_SEARCH,
235                                                 null,
236                                                 ApplicationMessage.WARNING));
237         return;
238       }
239       String resultType = null;
240       if (pageChecked) {
241         resultType = UIWCMSearchPortlet.SEARCH_PAGE_MODE;
242       } else {
243         resultType = UIWCMSearchPortlet.SEARCH_CONTENT_MODE;
244       }
245       String newKey = event.getRequestContext().getRequestParameter(OBJECTID);
246       if (newKey != null) {
247         keyword = newKey;
248         uiKeywordInput.setValue(newKey);
249       }
250       keyword = Normalizer.normalize(keyword, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
251       //keyword = keyword.replaceAll("'","''");
252       uiSearchResult.setResultType(resultType);
253       String selectedPortal = uiPortalSelectBox.getValue();
254       QueryCriteria queryCriteria = new QueryCriteria();
255 
256       List<String> documentNodeTypes = new ArrayList<String>();
257       if (documentChecked) {
258         TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
259         documentNodeTypes = templateService.getAllDocumentNodeTypes();
260         selectedPortal = Util.getPortalRequestContext().getPortalOwner();
261       } else {
262         documentNodeTypes.add("gtn:language");
263         documentNodeTypes.add("exo:pageMetadata");
264         queryCriteria.setFulltextSearchProperty(new String[] {"exo:metaKeywords", "exo:metaDescription", "gtn:name"});
265       }
266 
267       queryCriteria.setContentTypes(documentNodeTypes.toArray(new String[documentNodeTypes.size()]));
268 
269       queryCriteria.setSiteName(selectedPortal);
270       queryCriteria.setKeyword(
271                org.exoplatform.services.cms.impl.Utils.escapeIllegalCharacterInQuery(keyword));
272       if (documentChecked) {
273         queryCriteria.setSearchDocument(true);
274         queryCriteria.setSearchWebContent(true);
275       } else {
276         queryCriteria.setSearchDocument(false);
277         queryCriteria.setSearchWebContent(false);
278       }
279       queryCriteria.setSearchWebpage(pageChecked);
280       queryCriteria.setLiveMode(WCMComposer.MODE_LIVE.equals(Utils.getCurrentMode()));
281       int itemsPerPage = Integer.parseInt(portletPreferences.getValue(UIWCMSearchPortlet.ITEMS_PER_PAGE,
282                                                                       null));
283       queryCriteria.setPageMode(portletPreferences.getValue(UIWCMSearchPortlet.PAGE_MODE, null));
284       queryCriteria.setSortBy(sortField);
285       queryCriteria.setOrderBy(orderType);
286       try {
287         AbstractPageList<ResultNode> pageList = null;
288         if (pageChecked) {
289           pageList = siteSearchService.searchPageContents(WCMCoreUtils.getSystemSessionProvider(),
290                                                           queryCriteria,
291                                                           portletRequestContext.getLocale(),
292                                                           itemsPerPage,
293                                                           false);
294         } else {
295           pageList = siteSearchService.searchSiteContents(WCMCoreUtils.getUserSessionProvider(),
296                                                          queryCriteria,
297                                                          portletRequestContext.getLocale(),
298                                                          itemsPerPage,
299                                                          false);          
300         }        
301         
302         uiSearchResult.setPageList(pageList);
303         float timeSearch = pageList.getQueryTime() / 1000;
304         uiSearchResult.setSearchTime(timeSearch);        
305         if (pageList.getAvailable() <= 0) {
306           String suggestion = pageList.getSpellSuggestion();
307           uiSearchResult.setSuggestion(suggestion);
308           uiSearchForm.setSubmitAction(suggestion);
309         }
310         portletRequestContext.addUIComponentToUpdateByAjax(uiSearchResult);
311       } catch (Exception e) {
312         uiApp.addMessage(new ApplicationMessage(MESSAGE_NOT_SUPPORT_KEYWORD,
313                                                 null,
314                                                 ApplicationMessage.WARNING));
315         return;
316       }
317       portletRequestContext.addUIComponentToUpdateByAjax(uiSearchPageContainer);
318     }
319   }
320   
321   public UIFormRadioBoxInput getUIFormRadioBoxInput(String name)
322   {
323      return findComponentById(name);
324   }
325   
326 }