View Javadoc
1   /*
2    * Copyright (C) 2003-2007 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.ecm.webui.component.explorer.search;
18  
19  import java.util.ArrayList;
20  import java.util.Calendar;
21  import java.util.GregorianCalendar;
22  import java.util.List;
23  import java.util.ResourceBundle;
24  
25  import org.exoplatform.commons.utils.ISO8601;
26  import org.exoplatform.ecm.jcr.model.Preference;
27  import org.exoplatform.ecm.webui.component.explorer.UIJCRExplorer;
28  import org.exoplatform.ecm.webui.form.UIFormInputSetWithAction;
29  import org.exoplatform.ecm.webui.selector.UISelectable;
30  import org.exoplatform.web.application.RequestContext;
31  import org.exoplatform.webui.config.annotation.ComponentConfig;
32  import org.exoplatform.webui.core.UIPopupWindow;
33  import org.exoplatform.webui.core.model.SelectItemOption;
34  import org.exoplatform.webui.form.UIFormDateTimeInput;
35  import org.exoplatform.webui.form.UIFormSelectBox;
36  import org.exoplatform.webui.form.UIFormStringInput;
37  import org.exoplatform.webui.form.input.UICheckBoxInput;
38  import org.exoplatform.webui.form.validator.DateTimeValidator;
39  
40  @ComponentConfig(
41      template =  "app:/groovy/webui/component/explorer/search/UIConstraintsForm.gtmpl"
42  )
43  public class UIConstraintsForm extends UIFormInputSetWithAction implements UISelectable{
44  
45    final static public String OPERATOR = "operator" ;
46    final static public String TIME_OPTION = "timeOpt" ;
47    final static public String PROPERTY1 = "property1" ;
48    final static public String PROPERTY2 = "property2" ;
49    final static public String PROPERTY3 = "property3" ;
50    final static public String CONTAIN_EXACTLY = "containExactly" ;
51    final static public String CONTAIN = "contain" ;
52    final static public String NOT_CONTAIN = "notContain" ;
53    final static public String START_TIME = "startTime" ;
54    final static public String END_TIME = "endTime" ;
55    final static public String DOC_TYPE = "docType" ;
56    final static public String CATEGORY_TYPE = "categoryType" ;
57    final static public String AND_OPERATION = "and" ;
58    final static public String OR_OPERATION = "or" ;
59    final static public String CREATED_DATE = "CREATED" ;
60    final static public String MODIFIED_DATE = "MODIFIED" ;
61    final static public String EXACTLY_PROPERTY = "exactlyPro" ;
62    final static public String CONTAIN_PROPERTY = "containPro" ;
63    final static public String NOT_CONTAIN_PROPERTY = "notContainPro" ;
64    final static public String DATE_PROPERTY = "datePro" ;
65    final static public String NODETYPE_PROPERTY = "nodetypePro" ;
66    final static public String CATEGORY_PROPERTY = "categoryPro" ;
67    final static public String SPLIT_REGEX = "/|\\s+|:" ;
68    final static public String DATETIME_REGEX =
69      "^(\\d{1,2}\\/\\d{1,2}\\/\\d{1,4})\\s*(\\s+\\d{1,2}:\\d{1,2}:\\d{1,2})?$" ;
70  
71    private String              virtualDateQuery_;
72  
73    private String              _CREATED_DATE;
74  
75    private String              _MODIFIED_DATE;
76  
77    private String              _AND_OPERATION;
78  
79    private String              _OR_OPERATION;
80  
81    public UIConstraintsForm(String name) throws Exception {
82      super(name);
83      RequestContext context = RequestContext.getCurrentInstance();
84      ResourceBundle res = context.getApplicationResourceBundle();
85      _AND_OPERATION = res.getString("UIConstraintForm.label.and");
86      _OR_OPERATION = res.getString("UIConstraintForm.label.or");
87      _CREATED_DATE = res.getString("UIConstraintForm.label.created");
88      _MODIFIED_DATE = res.getString("UIConstraintForm.label.modified");
89      setActions(new String[] {"Add", "Cancel"}, null) ;
90      List<SelectItemOption<String>> typeOperation = new ArrayList<SelectItemOption<String>>() ;
91      typeOperation.add(new SelectItemOption<String>(_AND_OPERATION, AND_OPERATION));
92      typeOperation.add(new SelectItemOption<String>(_OR_OPERATION, OR_OPERATION));
93      addUIFormInput(new UIFormSelectBox(OPERATOR, OPERATOR, typeOperation)) ;
94  
95      addUIFormInput(new UICheckBoxInput(EXACTLY_PROPERTY, EXACTLY_PROPERTY, null)) ;
96      addUIFormInput(new UIFormStringInput(PROPERTY1, PROPERTY1, null)) ;
97      addUIFormInput(new UIFormStringInput(CONTAIN_EXACTLY, CONTAIN_EXACTLY, null)) ;
98  
99      addUIFormInput(new UICheckBoxInput(CONTAIN_PROPERTY, CONTAIN_PROPERTY, null)) ;
100     addUIFormInput(new UIFormStringInput(PROPERTY2, PROPERTY2, null)) ;
101     addUIFormInput(new UIFormStringInput(CONTAIN, CONTAIN, null)) ;
102 
103     addUIFormInput(new UICheckBoxInput(NOT_CONTAIN_PROPERTY, NOT_CONTAIN_PROPERTY, null)) ;
104     addUIFormInput(new UIFormStringInput(PROPERTY3, PROPERTY3, null)) ;
105     addUIFormInput(new UIFormStringInput(NOT_CONTAIN, NOT_CONTAIN, null)) ;
106 
107 
108     addUIFormInput(new UICheckBoxInput(DATE_PROPERTY, DATE_PROPERTY, null)) ;
109     List<SelectItemOption<String>> dateOperation = new ArrayList<SelectItemOption<String>>() ;
110     dateOperation.add(new SelectItemOption<String>(_CREATED_DATE, CREATED_DATE));
111     dateOperation.add(new SelectItemOption<String>(_MODIFIED_DATE, MODIFIED_DATE));
112     addUIFormInput(new UIFormSelectBox(TIME_OPTION, TIME_OPTION, dateOperation)) ;
113     UIFormDateTimeInput uiFromDate = new UIFormDateTimeInput(START_TIME, START_TIME, null) ;
114     uiFromDate.addValidator(DateTimeValidator.class);
115     uiFromDate.setDisplayTime(true) ;
116     addUIFormInput(uiFromDate) ;
117     UIFormDateTimeInput uiToDate = new UIFormDateTimeInput(END_TIME, END_TIME, null) ;
118     uiToDate.addValidator(DateTimeValidator.class);
119     uiToDate.setDisplayTime(true) ;
120     addUIFormInput(uiToDate) ;
121     addUIFormInput(new UICheckBoxInput(NODETYPE_PROPERTY, NODETYPE_PROPERTY, null)) ;
122     addUIFormInput(new UIFormStringInput(DOC_TYPE, DOC_TYPE, null)) ;
123     addUIFormInput(new UICheckBoxInput(CATEGORY_PROPERTY, CATEGORY_PROPERTY, null)) ;
124     addUIFormInput(new UIFormStringInput(CATEGORY_TYPE, CATEGORY_TYPE, null)) ;
125   }
126 
127   private String getContainQueryString(String property, String type, boolean isContain) {
128     String value = getUIStringInput(type).getValue() ;
129     if(value == null) return "" ;
130     if(value.trim().length() > 0) {
131       if(isContain) return " jcr:contains(@" + property.trim() + ", '"+ value.trim() + "')" ;
132       return " fn:not(jcr:contains(@" + property.trim() + ", '"+ value.trim() + "'))" ;
133     }
134     return "" ;
135   }
136 
137   private String getContainSQLQueryString(String property, String type, boolean isContain) {
138     String value = getUIStringInput(type).getValue();
139     if(value == null) return "";
140     if(value.trim().length() > 0) {
141       if(isContain) return " CONTAINS(" + property.trim() + ", '"+ value.trim() + "')";
142       return " NOT CONTAINS(" + property.trim() + ", '"+ value.trim() + "')";
143     }
144     return "";
145   }
146 
147   private String getDateTimeQueryString(String beforeDate, String afterDate, String type) {
148     Calendar bfDate = getUIFormDateTimeInput(START_TIME).getCalendar() ;
149     if(bfDate==null) return "";
150     if (afterDate != null && afterDate.trim().length() > 0) {
151       Calendar afDate = getUIFormDateTimeInput(END_TIME).getCalendar();
152       if (type.equals(CREATED_DATE)) {
153         virtualDateQuery_ = "(documents created from '" + beforeDate
154             + "') and (documents created to '" + afterDate + "')";
155         return "@exo:dateCreated >= xs:dateTime('" + ISO8601.format(bfDate)
156             + "') and @exo:dateCreated <= xs:dateTime('" + ISO8601.format(afDate) + "')";
157       } else if (type.equals(MODIFIED_DATE)) {
158         virtualDateQuery_ = "(documents modified from '" + beforeDate
159             + "') and (documents modified to '" + afterDate + "')";
160         return "@exo:dateModified >= xs:dateTime('" + ISO8601.format(bfDate)
161             + "') and @exo:dateModified <= xs:dateTime('" + ISO8601.format(afDate) + "')";
162       }
163     } else {
164       if(type.equals(CREATED_DATE)) {
165         virtualDateQuery_ = "(documents created from '"+beforeDate+"')" ;
166         return "@exo:dateCreated >= xs:dateTime('"+ISO8601.format(bfDate)+"')" ;
167       } else if(type.equals(MODIFIED_DATE)) {
168         virtualDateQuery_ = "(documents modified from '"+beforeDate+"')" ;
169         return "@exo:dateModified >= xs:dateTime('"+ISO8601.format(bfDate)+"')" ;
170       }
171     }
172     return "" ;
173   }
174 
175   private String getDateTimeSQLQueryString(String beforeDate, String afterDate, String type) {
176     Calendar bfDate = getUIFormDateTimeInput(START_TIME).getCalendar();
177     if(bfDate==null) return "";
178     if (afterDate != null && afterDate.trim().length() > 0) {
179       Calendar afDate = getUIFormDateTimeInput(END_TIME).getCalendar();
180       if (type.equals(CREATED_DATE)) {
181         virtualDateQuery_ = "(documents created from '" + beforeDate
182             + "') and (documents created to '" + afterDate + "')";
183         return "exo:dateCreated >= TIMESTAMP '" + ISO8601.format(bfDate)
184             + "' and exo:dateCreated <= TIMESTAMP '" + ISO8601.format(afDate) + "'";
185       } else if (type.equals(MODIFIED_DATE)) {
186         virtualDateQuery_ = "(documents modified from '" + beforeDate
187             + "') and (documents modified to '" + afterDate + "')";
188         return "exo:dateModified >= TIMESTAMP '" + ISO8601.format(bfDate)
189             + "' and exo:dateModified <= TIMESTAMP '" + ISO8601.format(afDate) + "'";
190       }
191     } else {
192       if(type.equals(CREATED_DATE)) {
193         virtualDateQuery_ = "(documents created from '"+beforeDate+"')";
194         return "exo:dateCreated >= TIMESTAMP '"+ISO8601.format(bfDate)+"'";
195       } else if(type.equals(MODIFIED_DATE)) {
196         virtualDateQuery_ = "(documents modified from '"+beforeDate+"')";
197         return "exo:dateModified >= TIMESTAMP '"+ISO8601.format(bfDate)+"'";
198       }
199     }
200     return "" ;
201   }
202 
203   private String getNodeTypeQueryString(String nodeTypes) {
204     StringBuffer advanceQuery = new StringBuffer();
205     String[] arrNodeTypes = {};
206     if (nodeTypes.indexOf(",") > -1)
207       arrNodeTypes = nodeTypes.split(",");
208     if (arrNodeTypes.length > 0) {
209       for (String nodeType : arrNodeTypes) {
210         if (advanceQuery.length() == 0)
211           advanceQuery.append("@jcr:primaryType = '").append(nodeType).append("'");
212         else
213           advanceQuery.append(" ")
214                       .append(OR_OPERATION)
215                       .append(" ")
216                       .append("@jcr:primaryType = '")
217                       .append(nodeType)
218                       .append("'");
219       }
220     } else {
221       advanceQuery.append("@jcr:primaryType = '").append(nodeTypes).append("'");
222     }
223     return advanceQuery.toString();
224   }
225 
226   private String getNodeTypeSQLQueryString(String nodeTypes) {
227     StringBuffer advanceQuery = new StringBuffer();
228     String[] arrNodeTypes = {};
229     if (nodeTypes.indexOf(",") > -1)
230       arrNodeTypes = nodeTypes.split(",");
231     if (arrNodeTypes.length > 0) {
232       for (String nodeType : arrNodeTypes) {
233         if (advanceQuery.length() == 0)
234           advanceQuery.append("jcr:primaryType = '").append(nodeType).append("'");
235         else
236           advanceQuery.append(" ")
237                       .append(OR_OPERATION)
238                       .append(" ")
239                       .append("jcr:primaryType = '")
240                       .append(nodeType)
241                       .append("'");
242       }
243     } else {
244       advanceQuery.append("jcr:primaryType = '").append(nodeTypes).append("'");
245     }
246     return advanceQuery.toString();
247   }
248 
249   /**
250    * Create query string for category
251    * @param categoryPath
252    * @return
253    */
254   private String getCategoryQueryString(String categoryPath) {
255     if (categoryPath == null || categoryPath.length() == 0) return "";
256     return ("@exo:category = '" + categoryPath + "'");
257   }
258 
259   private String getCategorySQLQueryString(String categoryPath) {
260     if (categoryPath == null || categoryPath.length() == 0) return "";
261     return ("exo:category = '" + categoryPath + "'");
262   }
263 
264   void addConstraint(int opt) throws Exception {
265     String advanceQuery = "" ;
266     String property ;
267     virtualDateQuery_ = null ;
268     UISimpleSearch uiSimpleSearch = this.getParent();
269     UIJCRExplorer uiExplorer = uiSimpleSearch.getAncestorOfType(UIJCRExplorer.class);
270     Preference pref = uiExplorer.getPreference();
271     String queryType = pref.getQueryType();
272     switch (opt) {
273       case 0:
274         property = getUIStringInput(PROPERTY1).getValue() ;
275         String value = getUIStringInput(CONTAIN_EXACTLY).getValue() ;
276         if (queryType.equals(Preference.XPATH_QUERY))
277           advanceQuery = "@" + property + " = '" + value.trim() + "'" ;
278         else
279           advanceQuery = " CONTAINS(" + property + ", '" + value.trim() + "')" ;
280         break;
281       case 1:
282         property = getUIStringInput(PROPERTY2).getValue() ;
283         if (queryType.equals(Preference.XPATH_QUERY))
284           advanceQuery = getContainQueryString(property, CONTAIN, true);
285         else
286           advanceQuery = getContainSQLQueryString(property, CONTAIN, true);
287         break;
288       case 2:
289         property = getUIStringInput(PROPERTY3).getValue();
290         if (queryType.equals(Preference.XPATH_QUERY))
291           advanceQuery = getContainQueryString(property, NOT_CONTAIN, false);
292         else
293           advanceQuery = getContainSQLQueryString(property, NOT_CONTAIN, false);
294         break;
295       case 3:
296         String fromDate = getUIFormDateTimeInput(START_TIME).getValue() ;
297         String toDate = getUIFormDateTimeInput(END_TIME).getValue() ;
298         String type = getUIFormSelectBox(TIME_OPTION).getValue() ;
299         if (queryType.equals(Preference.XPATH_QUERY))
300           advanceQuery = getDateTimeQueryString(fromDate, toDate, type);
301         else
302           advanceQuery = getDateTimeSQLQueryString(fromDate, toDate, type);
303         break ;
304       case 4:
305         property = getUIStringInput(DOC_TYPE).getValue();
306         if (queryType.equals(Preference.XPATH_QUERY))
307           advanceQuery = getNodeTypeQueryString(property);
308         else
309           advanceQuery = getNodeTypeSQLQueryString(property);
310         break;
311       case 5:
312         property = getUIStringInput(CATEGORY_TYPE).getValue();
313         if (queryType.equals(Preference.XPATH_QUERY))
314           advanceQuery = getCategoryQueryString(property);
315         else
316           advanceQuery = getCategorySQLQueryString(property);
317         String firstOperator = uiSimpleSearch.getUIStringInput(UISimpleSearch.FIRST_OPERATOR).getValue();
318         if (!uiSimpleSearch.getCategoryPathList().contains(property) && firstOperator.equals("and"))
319           uiSimpleSearch.getCategoryPathList().add(property);
320         break;
321       default:
322         break;
323     }
324     uiSimpleSearch.updateAdvanceConstraint(advanceQuery,
325                                            getUIFormSelectBox(OPERATOR).getValue(),
326                                            virtualDateQuery_);
327   }
328 
329   void resetConstraintForm() {
330     reset();
331     getUICheckBoxInput(EXACTLY_PROPERTY).setChecked(false);
332     getUICheckBoxInput(CONTAIN_PROPERTY).setChecked(false);
333     getUICheckBoxInput(NOT_CONTAIN_PROPERTY).setChecked(false);
334     getUICheckBoxInput(DATE_PROPERTY).setChecked(false);
335     getUICheckBoxInput(NODETYPE_PROPERTY).setChecked(false);
336     getUICheckBoxInput(CATEGORY_PROPERTY).setChecked(false);
337   }
338 
339   boolean isValidDateTime(String dateTime) {
340     String[] arr = dateTime.split(SPLIT_REGEX, 7) ;
341     int valid = Integer.parseInt(arr[0]) ;
342     if(valid < 1 || valid > 12) return false;
343     Calendar date = new GregorianCalendar(Integer.parseInt(arr[2]), valid - 1, 1) ;
344     if(Integer.parseInt(arr[1]) > date.getActualMaximum(Calendar.DAY_OF_MONTH)) return false;
345     if (arr.length > 3
346         && (Integer.parseInt(arr[3]) > 23 || Integer.parseInt(arr[4]) > 59 || Integer.parseInt(arr[5]) > 59))
347       return false;
348     return true;
349   }
350 
351   /**
352    * Set category to text box and closeof choose category popup window
353    * @param selectField: name of text field input
354    * @param value: value of chosen category
355    * @throws Exception
356    */
357   public void doSelect(String selectField, Object value) throws Exception {
358     /* Set value to textbox */
359     if (value==null) {
360       getUIStringInput(selectField).setValue("");
361       getUICheckBoxInput(UIConstraintsForm.CATEGORY_PROPERTY).setChecked(false);
362     }else {
363       getUIStringInput(selectField).setValue(value.toString());
364       /* Set value for checkBox is checked */
365       getUICheckBoxInput(UIConstraintsForm.CATEGORY_PROPERTY).setChecked(true);
366     }
367     UISearchContainer uiSearchContainer = getAncestorOfType(UISearchContainer.class);
368     /*
369      *  Close popup window when finish choose category
370      */
371     UIPopupWindow uiPopup = uiSearchContainer.findComponentById(UISearchContainer.CATEGORY_POPUP);
372     uiPopup.setRendered(false);
373     uiPopup.setShow(false);
374   }
375 
376   public UIFormDateTimeInput getUIFormDateTimeInput(String name) {
377     return findComponentById(name);
378   }
379 }