BrightSide Workbench Full Report + Source Code
FilterField.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2011 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 package org.turro.zkoss.filter;
19 
20 import java.io.Serializable;
21 import java.util.Date;
22 import java.util.EnumSet;
23 import org.turro.string.Strings;
24 import org.turro.elephant.db.SQLHelper;
25 import org.turro.elephant.db.WhereClause;
26 import org.turro.elephant.impl.util.StringParser;
27 import org.turro.plugin.filter.IFilterValue;
28 import org.turro.zkoss.dialog.InputEnum;
29 import org.turro.zkoss.input.*;
30 import org.zkoss.zk.ui.HtmlBasedComponent;
31 import org.zkoss.zk.ui.ext.AfterCompose;
32 import org.zkoss.zul.*;
33 
38 public abstract class FilterField implements Cloneable, Serializable, IFilterValue, AfterCompose {
39 
40  public final static String FIELD_SUBSTITUTION_REGEXP = "[\\.\\(\\) \\,\\:\\<\\>\\=]";
41 
42  protected EnumSet<FilterFieldOperator> operators;
43  protected HtmlBasedComponent editor, operatorEditor;
44  protected EnumListbox<ChainOperator> chainEditor;
45  protected Object value;
46  protected int scale;
47  protected boolean fixed;
48  protected String label, format;
49  protected Enum[] choices;
50  protected ChainOperator chain;
52 
53  public FilterField(String label, String value) {
55  }
56 
57  public FilterField(String label, Number value) {
59  }
60 
61  public FilterField(String label, Date value) {
63  }
64 
65  public FilterField(String label, Boolean value) {
67  }
68 
69  public FilterField(String label, Enum value) {
71  }
72 
73  public FilterField(String label) {
75  }
76 
77  public FilterField(String label, String value, FilterFieldOperator operator) {
78  this.label = label;
79  this.value = value;
80  this.operator = operator;
81  operators = EnumSet.of(
91  }
92 
93  public FilterField(String label, Number value, FilterFieldOperator operator) {
94  this.label = label;
95  this.value = value;
96  this.operator = operator;
97  this.scale = 2;
98  operators = EnumSet.of(
106  }
107 
108  public FilterField(String label, Date value, FilterFieldOperator operator) {
109  this.label = label;
110  this.value = value;
111  this.operator = operator;
112  operators = EnumSet.of(
120  }
121 
122  public FilterField(String label, Boolean value, FilterFieldOperator operator) {
123  this.label = label;
124  this.value = value;
125  this.operator = operator;
126  operators = EnumSet.of(
130  }
131 
132  public FilterField(String label, Enum value, FilterFieldOperator operator) {
133  this.label = label;
134  this.value = value;
135  this.operator = operator;
136  operators = EnumSet.of(
140  }
141 
142  public FilterField(String label, FilterFieldOperator operator) {
143  this.label = label;
144  this.value = null;
145  this.editor = null;
146  this.operator = operator;
147  operators = EnumSet.of(
151  }
152 
154  if(chainEditor != null) {
155  return (ChainOperator) ((EnumListbox) chainEditor).getObjectValue();
156  }
157  return chain;
158  }
159 
160  public void setChain(ChainOperator chain) {
161  this.chain = chain;
162  }
163 
164  public Enum[] getChoices() {
165  return choices;
166  }
167 
168  public void setChoices(Enum[] choices) {
169  this.choices = choices;
170  }
171 
172  public boolean isFixed() {
173  return fixed;
174  }
175 
176  public void setFixed(boolean fixed) {
177  this.fixed = fixed;
178  }
179 
180  public String getFormat() {
181  return format;
182  }
183 
184  public void setFormat(String format) {
185  this.format = format;
186  }
187 
188  @Override
189  public String getLabel() {
190  return label;
191  }
192 
193  public void setLabel(String label) {
194  this.label = label;
195  }
196 
197  public EnumSet<FilterFieldOperator> getOperators() {
198  return operators;
199  }
200 
201  public void setOperators(EnumSet<FilterFieldOperator> operators) {
202  this.operators = operators;
203  }
204 
206  if(operatorEditor != null) {
207  return (FilterFieldOperator) ((EnumListbox) operatorEditor).getObjectValue();
208  }
209  return operator;
210  }
211 
212  public void setOperator(FilterFieldOperator operator) {
213  this.operator = operator;
214  }
215 
216  public int getScale() {
217  return scale;
218  }
219 
220  public void setScale(int scale) {
221  this.scale = scale;
222  }
223 
224  public Object getObjectValue() {
225  return getEditorValue();
226  }
227 
228  @Override
229  public boolean hasValue() {
230  Object v = getObjectValue();
231  if(v instanceof String) {
232  if(Strings.isBlank((String) v)) {
233  return false;
234  }
235  }
236  return v != null;
237  }
238 
239  public HtmlBasedComponent getEditor() {
240  if(editor == null) {
241  editor = createEditor();
242  editor.setHflex("1");
243  }
244 // if(editor instanceof Decimalbox) {
245 // editor.setWidth("100%");
246 // } else if(editor instanceof Datebox) {
247 // editor.setWidth("80px");
248 // } else if(editor instanceof Combobox) {
249 // editor.setWidth("95%");
250 // } else if(editor instanceof Textbox) {
251 // editor.setWidth("100%");
252 // }
253  return editor;
254  }
255 
256  public HtmlBasedComponent getOperatorEditor() {
257  if(operatorEditor == null) {
258  operatorEditor = createOperatorEditor();
259  operatorEditor.setHflex("1");
260  }
261  return operatorEditor;
262  }
263 
264  public EnumListbox<ChainOperator> getChainEditor() {
265  if(chainEditor == null) {
267  chainEditor.setHflex("1");
268  }
269  return chainEditor;
270  }
271 
272  protected HtmlBasedComponent createEditor() {
273  if(value instanceof Boolean) {
274  Checkbox cb = new Checkbox();
275  cb.setChecked((Boolean) value);
276  return cb;
277  } else if(value instanceof Number) {
278  ExpressionInput ei = new ExpressionInput();
279  ei.setValue(value);
280  return ei;
281  } else if(value instanceof Date) {
282  DateboxShort db = new DateboxShort((Date) value);
283  db.setFormat(format);
284  return db;
285  } else if(value instanceof Enum) {
286  InputEnum ie = new InputEnum(choices);
287  ie.setObjectValue((Enum) value);
288  return ie;
289  } else {
290  Textbox tb = new Textbox((String) value);
291  return tb;
292  }
293  }
294 
295  protected HtmlBasedComponent createOperatorEditor() {
296  EnumListbox<FilterFieldOperator> col = new EnumListbox<FilterFieldOperator>(operators.toArray(new FilterFieldOperator[0]));
297  col.setObjectValue(operator);
298  col.setMold("select");
299  //col.afterCompose();
300  return col;
301  }
302 
303  protected EnumListbox<ChainOperator> createChainEditor() {
304  EnumListbox<ChainOperator> col = new EnumListbox<ChainOperator>(ChainOperator.values());
305  col.setObjectValue(chain);
306  col.setMold("select");
307  //col.afterCompose();
308  return col;
309  }
310 
311  protected Object getEditorValue() {
312  if(editor instanceof Checkbox) {
313  return ((Checkbox) editor).isChecked();
314  } else if(editor instanceof Decimalbox) {
315  return StringParser.convertToClass(value.getClass(), ((Decimalbox) editor).getValue());
316  } else if(editor instanceof ExpressionInput) {
317  return StringParser.convertToClass(value.getClass(), ((ExpressionInput) editor).getNumber(scale));
318  } else if(editor instanceof Datebox) {
319  return ((Datebox) editor).getValue();
320  } else if(editor instanceof GenericListbox) {
321  return ((GenericListbox) editor).getObjectValue();
322  } else if(editor instanceof GenericCombobox) {
323  return ((GenericCombobox) editor).getObjectValue();
324  } else if(editor instanceof Listbox) {
325  return ((Listbox) editor).getSelectedItem().getValue();
326  } else if(editor instanceof InputEnum) {
327  return ((InputEnum) editor).getObjectValue();
328  } else {
329  return ((Textbox) editor).getText();
330  }
331  }
332 
333  @Override
334  public abstract void addConstraint(WhereClause wc);
335 
336  public void doAddConstraint(WhereClause wc, String field) {
337  doAddConstraint(wc, new String[] { field });
338  }
339 
340  public void doAddConstraint(WhereClause wc, String[] fields) {
341  if(!hasValue()) return;
342  Object obj = getObjectValue();
344  if(obj instanceof String) {
345  String prefix = wc.getPrefix();
346  wc.setPrefix(getChain().getOpSQL());
347  wc = SQLHelper.getWhereClause(wc, fields, ((String) obj).replaceAll("\\*", "%"));
348  wc.setPrefix(prefix);
349  }
350  } else if(FilterFieldOperator.FILTER_REGEXP.equals(getOperator())) {
351 
352  } else {
353  String param = fields[0].replaceAll(FIELD_SUBSTITUTION_REGEXP, "_") + wc.getUniqueSuffix();
354  wc.addClause(getChain().getOpSQL() + " " + fields[0] + " " + getOperator().getOpSQL() + " :" + param);
355  wc.addNamedValue(param, obj);
356  }
357  }
358 
359  public void doAddSubqueryConstraint(WhereClause wc, String collection, String field) {
360  doAddSubqueryConstraint(wc, collection, new String[] { field });
361  }
362 
363  public void doAddSubqueryConstraint(WhereClause wc, String collection, String[] fields) {
364  if(!hasValue()) return;
365  Object obj = getObjectValue();
367  String param = fields[0].replaceAll(FIELD_SUBSTITUTION_REGEXP, "_") + wc.getUniqueSuffix();
368  wc.addClause(getChain().getOpSQL() + " exists");
369  wc.addClause("(");
370  wc.addClause("select sqx from " + collection + " as sqx");
371  wc.addClause("where sqx." + fields[0] + " " + getOperator().getOpSQL() + " :" + param);
372  wc.addNamedValue(param, ((String) obj).replaceAll("\\*", "%"));
373  wc.addClause(")");
374  } else if(FilterFieldOperator.FILTER_REGEXP.equals(getOperator())) {
375 
376  } else {
377  String param = fields[0].replaceAll(FIELD_SUBSTITUTION_REGEXP, "_") + wc.getUniqueSuffix();
378  wc.addClause(getChain().getOpSQL() + " exists");
379  wc.addClause("(");
380  wc.addClause("select sqx from " + collection + " as sqx");
381  wc.addClause("where sqx." + fields[0] + " " + getOperator().getOpSQL() + " :" + param);
382  wc.addNamedValue(param, obj);
383  wc.addClause(")");
384  }
385  }
386 
387  public void doAddSubqueryConstraint(WhereClause wc, String collection[], String field) {
388  doAddSubqueryConstraint(wc, collection, new String[] { field });
389  }
390 
391  public void doAddSubqueryConstraint(WhereClause wc, String collection[], String[] fields) {
392  if(!hasValue()) return;
393  Object obj = getObjectValue();
395  addLikeSubqueries(wc, collection, fields, 0);
396  } else if(FilterFieldOperator.FILTER_REGEXP.equals(getOperator())) {
397 
398  } else {
399  addSubqueries(wc, collection, fields, 0);
400  }
401  }
402 
403  private void addSubqueries(WhereClause wc, String collection[], String[] fields, int count) {
404  if(count >= collection.length) return;
405  String param = fields[0].replaceAll(FIELD_SUBSTITUTION_REGEXP, "_") + wc.getUniqueSuffix();
406  if(count == 0) {
407  wc.addClause(getChain().getOpSQL() + " exists");
408  } else {
409  wc.addClause("where exists");
410  }
411  wc.addClause("(");
412  wc.addClause("select sqx from " + collection[count] + " as sqx");
413  if(count == collection.length - 1) {
414  Object obj = getObjectValue();
415  wc.addClause("where sqx." + fields[0] + " " + getOperator().getOpSQL() + " :" + param);
416  wc.addNamedValue(param, obj);
417  } else {
418  addSubqueries(wc, collection, fields, count + 1);
419  }
420  wc.addClause(")");
421  }
422 
423  private void addLikeSubqueries(WhereClause wc, String collection[], String[] fields, int count) {
424  if(count >= collection.length) return;
425  String param = fields[0].replaceAll(FIELD_SUBSTITUTION_REGEXP, "_") + wc.getUniqueSuffix();
426  if(count == 0) {
427  wc.addClause(getChain().getOpSQL() + " exists");
428  } else {
429  wc.addClause("where exists");
430  }
431  wc.addClause("(");
432  wc.addClause("select sqx from " + collection[count] + " as sqx");
433  if(count == collection.length - 1) {
434  Object obj = getObjectValue();
435  wc.addClause("where sqx." + fields[0] + " " + getOperator().getOpSQL() + " :" + param);
436  wc.addNamedValue(param, ((String) obj).replaceAll("\\*", "%"));
437  } else {
438  addLikeSubqueries(wc, collection, fields, count + 1);
439  }
440  wc.addClause(")");
441  }
442 
443  @Override
444  public void afterCompose() {
445  if(editor != null && editor instanceof AfterCompose) {
446  ((AfterCompose) editor).afterCompose();
447  }
448  if(operatorEditor != null && operatorEditor instanceof AfterCompose) {
449  ((AfterCompose) operatorEditor).afterCompose();
450  }
451  if(chainEditor != null && chainEditor instanceof AfterCompose) {
452  ((AfterCompose) chainEditor).afterCompose();
453  }
454  }
455 
456  @Override
457  public Object clone() {
458  try {
459  return super.clone();
460  } catch (CloneNotSupportedException e) {
461  return null;
462  }
463  }
464 
465 }
static WhereClause getWhereClause(String[] fields, String value)
Definition: SQLHelper.java:64
void addNamedValue(String name, Object value)
static Object convertToClass(Class javaClass, Object value)
abstract void addConstraint(WhereClause wc)
void doAddSubqueryConstraint(WhereClause wc, String collection[], String field)
HtmlBasedComponent createOperatorEditor()
EnumListbox< ChainOperator > chainEditor
void doAddSubqueryConstraint(WhereClause wc, String collection, String field)
void doAddConstraint(WhereClause wc, String field)
void doAddConstraint(WhereClause wc, String[] fields)
static final String FIELD_SUBSTITUTION_REGEXP
FilterField(String label, Number value)
void setChain(ChainOperator chain)
EnumSet< FilterFieldOperator > getOperators()
FilterField(String label, Date value, FilterFieldOperator operator)
FilterFieldOperator getOperator()
EnumListbox< ChainOperator > getChainEditor()
FilterField(String label, Enum value, FilterFieldOperator operator)
HtmlBasedComponent createEditor()
EnumListbox< ChainOperator > createChainEditor()
void doAddSubqueryConstraint(WhereClause wc, String collection[], String[] fields)
void doAddSubqueryConstraint(WhereClause wc, String collection, String[] fields)
FilterField(String label, Boolean value, FilterFieldOperator operator)
FilterField(String label, String value)
FilterField(String label, Date value)
FilterField(String label, Enum value)
FilterField(String label, Number value, FilterFieldOperator operator)
EnumSet< FilterFieldOperator > operators
FilterField(String label, String value, FilterFieldOperator operator)
void setOperators(EnumSet< FilterFieldOperator > operators)
FilterField(String label, Boolean value)
void setOperator(FilterFieldOperator operator)
FilterField(String label, FilterFieldOperator operator)
HtmlBasedComponent getOperatorEditor()