001/* 002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Anahide Tchertchian 018 */ 019package org.nuxeo.ecm.platform.smart.query; 020 021import java.util.ArrayList; 022import java.util.Date; 023import java.util.List; 024 025import org.apache.commons.lang.StringUtils; 026 027/** 028 * Smart query providing all the needed methods for UI interaction that will make it possible to build a query adding 029 * clauses step by step. 030 * <p> 031 * Specific getters and setters have been defined instead of a generic one for a better resolution of target types. 032 * 033 * @since 5.4 034 * @author Anahide Tchertchian 035 */ 036public abstract class IncrementalSmartQuery implements SmartQuery { 037 038 private static final long serialVersionUID = 1L; 039 040 /** 041 * Stores the current existing query part. 042 * <p> 043 * This does not need to be a valid query as it can still be refined after. 044 */ 045 protected String existingQueryPart; 046 047 /** 048 * String containing the logical operator at start of the query part to add (for instance 'AND' or 'OR'). 049 */ 050 protected String logicalOperator; 051 052 /** 053 * Boolean indicating if the query part to add should be negated (for instance by adding the 'NOT' marker before) 054 */ 055 protected Boolean addNotOperator; 056 057 /** 058 * Boolean indicating if an open parenthesis should be added prior to the query part to add. 059 */ 060 protected Boolean openParenthesis; 061 062 /** 063 * Boolean indicating if an closed parenthesis should be added after the query part to add. 064 */ 065 protected Boolean closeParenthesis; 066 067 /** 068 * Marker for layout row selection that will make it possible to display only the widgets defined in this row for 069 * the rest of the query part definition. 070 */ 071 protected String selectedRowName; 072 073 /** 074 * String typically representing the search index for the query part to add. 075 */ 076 protected String leftExpression; 077 078 /** 079 * String representing the conditional operator to use when building the query part to add (for instance '=', 080 * 'LIKE',...) 081 */ 082 protected String conditionalOperator; 083 084 protected Boolean escapeValue; 085 086 /** 087 * Generic set value for the new query part to add. 088 * <p> 089 * Holds the last value set on one of the specific value setters. 090 */ 091 protected Object value; 092 093 // provide a separate field for accepted expression values for a good JFS 094 // resolution 095 096 /** 097 * Boolean value binding. 098 */ 099 protected Boolean booleanValue; 100 101 /** 102 * String value binding. 103 */ 104 protected String stringValue; 105 106 /** 107 * String list value binding. 108 */ 109 protected List<String> stringListValue; 110 111 /** 112 * String array value binding. 113 */ 114 protected String[] stringArrayValue; 115 116 /** 117 * Date and time value binding. 118 */ 119 protected Date datetimeValue; 120 121 /** 122 * Another date and time value binding (useful when using the 'BETWEEN' operator for instance) 123 */ 124 protected Date otherDatetimeValue; 125 126 /** 127 * Date value binding 128 */ 129 protected Date dateValue; 130 131 /** 132 * Another date value binding (useful when using the 'BETWEEN' operator for instance) 133 */ 134 protected Date otherDateValue; 135 136 /** 137 * Integer value binding. 138 */ 139 protected Long integerValue; 140 141 /** 142 * Float value binding. 143 */ 144 protected Double floatValue; 145 146 public IncrementalSmartQuery(String existingQueryPart) { 147 super(); 148 this.existingQueryPart = existingQueryPart; 149 } 150 151 public String getExistingQueryPart() { 152 return existingQueryPart; 153 } 154 155 public void setExistingQueryPart(String existingQueryPart) { 156 this.existingQueryPart = existingQueryPart; 157 } 158 159 /** 160 * Returns true if existing query part is not empty. 161 */ 162 public boolean getShowLogicalOperator() { 163 if (existingQueryPart == null || existingQueryPart.trim().length() == 0) { 164 return false; 165 } 166 return true; 167 } 168 169 public String getLogicalOperator() { 170 return logicalOperator; 171 } 172 173 public void setLogicalOperator(String logicalOperator) { 174 this.logicalOperator = logicalOperator; 175 } 176 177 public boolean getShowAddNotOperator() { 178 return true; 179 } 180 181 public Boolean getAddNotOperator() { 182 return addNotOperator; 183 } 184 185 public void setAddNotOperator(Boolean addNotOperator) { 186 this.addNotOperator = addNotOperator; 187 } 188 189 /** 190 * Returns true 191 */ 192 public boolean getShowOpenParenthesis() { 193 return true; 194 } 195 196 public Boolean getOpenParenthesis() { 197 return openParenthesis; 198 } 199 200 public void setOpenParenthesis(Boolean openParenthesis) { 201 this.openParenthesis = openParenthesis; 202 } 203 204 /** 205 * Returns true if there are strictly more open parenthesis in the existing query part than closed ones. 206 */ 207 public boolean getShowCloseParenthesis() { 208 if (existingQueryPart != null) { 209 int numberOpened = StringUtils.countMatches(existingQueryPart, "("); 210 int numberClosed = StringUtils.countMatches(existingQueryPart, ")"); 211 if (numberOpened > numberClosed) { 212 return true; 213 } 214 } 215 return false; 216 } 217 218 public Boolean getCloseParenthesis() { 219 return closeParenthesis; 220 } 221 222 public void setCloseParenthesis(Boolean closeParenthesis) { 223 this.closeParenthesis = closeParenthesis; 224 } 225 226 public String getSelectedRowName() { 227 return selectedRowName; 228 } 229 230 /** 231 * Sets the selected row name. 232 * <p> 233 * Also resets the left expression, conditional operator, and all value bindings, as they may be set to values that 234 * are not relevant in this new row context. 235 */ 236 public void setSelectedRowName(String selectedRowName) { 237 this.selectedRowName = selectedRowName; 238 leftExpression = null; 239 conditionalOperator = null; 240 clearValues(); 241 } 242 243 // TODO: will be useful if layout tag can use it to filter other rows, see 244 // NXP-5725 245 public List<String> getSelectedRowNames() { 246 List<String> res = new ArrayList<String>(); 247 if (selectedRowName != null) { 248 res.add(selectedRowName); 249 } 250 return res; 251 } 252 253 public String getLeftExpression() { 254 return leftExpression; 255 } 256 257 public void setLeftExpression(String leftExpression) { 258 this.leftExpression = leftExpression; 259 } 260 261 public String getConditionalOperator() { 262 return conditionalOperator; 263 } 264 265 /** 266 * Sets the conditional operator. 267 * <p> 268 * Also resets all the value bindings, as they may be set to values that are not relevant in this new conditional 269 * operator context. 270 */ 271 public void setConditionalOperator(String conditionalOperator) { 272 this.conditionalOperator = conditionalOperator; 273 clearValues(); 274 } 275 276 public Boolean getEscapeValue() { 277 return escapeValue; 278 } 279 280 public void setEscapeValue(Boolean escapeValue) { 281 this.escapeValue = escapeValue; 282 } 283 284 public Object getValue() { 285 return value; 286 } 287 288 public void setValue(Object value) { 289 this.value = value; 290 } 291 292 public Boolean getBooleanValue() { 293 return booleanValue; 294 } 295 296 public void setBooleanValue(Boolean booleanValue) { 297 this.booleanValue = booleanValue; 298 setValue(booleanValue); 299 } 300 301 public String getStringValue() { 302 return stringValue; 303 } 304 305 public void setStringValue(String stringValue) { 306 this.stringValue = stringValue; 307 setValue(stringValue); 308 } 309 310 public List<String> getStringListValue() { 311 return stringListValue; 312 } 313 314 public void setStringListValue(List<String> stringListValue) { 315 this.stringListValue = stringListValue; 316 setValue(stringListValue); 317 } 318 319 public String[] getStringArrayValue() { 320 return stringArrayValue; 321 } 322 323 public void setStringArrayValue(String[] stringArrayValue) { 324 this.stringArrayValue = stringArrayValue; 325 setValue(stringArrayValue); 326 } 327 328 public Date getDatetimeValue() { 329 return datetimeValue; 330 } 331 332 public void setDatetimeValue(Date datetimeValue) { 333 this.datetimeValue = datetimeValue; 334 setValue(datetimeValue); 335 } 336 337 public Date getOtherDatetimeValue() { 338 return otherDatetimeValue; 339 } 340 341 public void setOtherDatetimeValue(Date otherDatetimeValue) { 342 this.otherDatetimeValue = otherDatetimeValue; 343 setValue(otherDatetimeValue); 344 } 345 346 public Date getDateValue() { 347 return dateValue; 348 } 349 350 public void setDateValue(Date dateValue) { 351 this.dateValue = dateValue; 352 setValue(dateValue); 353 } 354 355 public Date getOtherDateValue() { 356 return otherDateValue; 357 } 358 359 public void setOtherDateValue(Date otherDateValue) { 360 this.otherDateValue = otherDateValue; 361 setValue(otherDateValue); 362 } 363 364 public Long getIntegerValue() { 365 return integerValue; 366 } 367 368 public void setIntegerValue(Long integerValue) { 369 this.integerValue = integerValue; 370 setValue(integerValue); 371 } 372 373 public Double getFloatValue() { 374 return floatValue; 375 } 376 377 public void setFloatValue(Double floatValue) { 378 this.floatValue = floatValue; 379 setValue(floatValue); 380 } 381 382 /** 383 * Clears all field values, except the existing quedry part. 384 */ 385 protected void clear() { 386 logicalOperator = null; 387 addNotOperator = null; 388 openParenthesis = null; 389 closeParenthesis = null; 390 selectedRowName = null; 391 leftExpression = null; 392 conditionalOperator = null; 393 clearValues(); 394 } 395 396 /** 397 * Clears all value bindings. 398 */ 399 protected void clearValues() { 400 escapeValue = null; 401 value = null; 402 booleanValue = null; 403 stringValue = null; 404 stringListValue = null; 405 stringArrayValue = null; 406 datetimeValue = null; 407 otherDatetimeValue = null; 408 dateValue = null; 409 otherDateValue = null; 410 integerValue = null; 411 floatValue = null; 412 } 413 414}