1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.dao.impl;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.ojb.broker.query.Criteria;
21 import org.apache.ojb.broker.query.Query;
22 import org.apache.ojb.broker.query.QueryByCriteria;
23 import org.apache.ojb.broker.query.QueryFactory;
24 import org.kuali.rice.core.api.datetime.DateTimeService;
25 import org.kuali.rice.core.api.search.SearchOperator;
26 import org.kuali.rice.core.api.util.RiceKeyConstants;
27 import org.kuali.rice.core.api.util.type.TypeUtils;
28 import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbCharBooleanConversion;
29 import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
30 import org.kuali.rice.core.framework.persistence.platform.DatabasePlatform;
31 import org.kuali.rice.kns.service.KNSServiceLocator;
32 import org.kuali.rice.krad.bo.BusinessObject;
33 import org.kuali.rice.krad.bo.InactivatableFromTo;
34 import org.kuali.rice.krad.dao.LookupDao;
35 import org.kuali.rice.krad.lookup.CollectionIncomplete;
36 import org.kuali.rice.krad.lookup.LookupUtils;
37 import org.kuali.rice.krad.service.DataDictionaryService;
38 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
39 import org.kuali.rice.krad.service.PersistenceStructureService;
40 import org.kuali.rice.krad.util.GlobalVariables;
41 import org.kuali.rice.krad.util.KRADConstants;
42 import org.kuali.rice.krad.util.KRADPropertyConstants;
43 import org.kuali.rice.krad.util.ObjectUtils;
44 import org.springframework.dao.DataIntegrityViolationException;
45 import org.springmodules.orm.ojb.OjbOperationException;
46
47 import java.math.BigDecimal;
48 import java.sql.Timestamp;
49 import java.text.ParseException;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Map;
55
56
57
58
59
60
61 @Deprecated
62 public class LookupDaoOjb extends PlatformAwareDaoBaseOjb implements LookupDao {
63 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupDaoOjb.class);
64 private DateTimeService dateTimeService;
65 private PersistenceStructureService persistenceStructureService;
66 private DataDictionaryService dataDictionaryService;
67
68
69
70
71
72
73
74
75
76
77 public Collection findCollectionBySearchHelper(Class businessObjectClass, Map formProps, boolean unbounded,
78 boolean usePrimaryKeyValuesOnly) {
79 Integer searchResultsLimit = org.kuali.rice.kns.lookup.LookupUtils.getSearchResultsLimit(businessObjectClass);
80 return findCollectionBySearchHelper(businessObjectClass, formProps, unbounded, usePrimaryKeyValuesOnly,
81 searchResultsLimit);
82 }
83
84
85
86
87
88
89
90 public Collection findCollectionBySearchHelper(Class businessObjectClass, Map formProps, boolean unbounded,
91 boolean usePrimaryKeyValuesOnly, Integer searchResultsLimit) {
92 BusinessObject businessObject = checkBusinessObjectClass(businessObjectClass);
93 if (usePrimaryKeyValuesOnly) {
94 return executeSearch(businessObjectClass, getCollectionCriteriaFromMapUsingPrimaryKeysOnly(
95 businessObjectClass, formProps), unbounded, searchResultsLimit);
96 }
97
98 Criteria crit = getCollectionCriteriaFromMap(businessObject, formProps);
99 return executeSearch(businessObjectClass, crit, unbounded, searchResultsLimit);
100 }
101
102
103
104
105 public Criteria getCollectionCriteriaFromMap(BusinessObject example, Map formProps) {
106 Criteria criteria = new Criteria();
107 Iterator propsIter = formProps.keySet().iterator();
108 while (propsIter.hasNext()) {
109 String propertyName = (String) propsIter.next();
110 Boolean caseInsensitive = Boolean.TRUE;
111 if ( KRADServiceLocatorWeb.getDataDictionaryService().isAttributeDefined( example.getClass(), propertyName )) {
112
113
114
115 caseInsensitive = !KRADServiceLocatorWeb.getDataDictionaryService().getAttributeForceUppercase( example.getClass(), propertyName );
116 }
117 if ( caseInsensitive == null ) { caseInsensitive = Boolean.TRUE; }
118 boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocator
119 .getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(example.getClass(), propertyName);
120
121 if (formProps.get(propertyName) instanceof Collection) {
122 Iterator iter = ((Collection) formProps.get(propertyName)).iterator();
123 while (iter.hasNext()) {
124 String searchValue = (String) iter.next();
125 if (!caseInsensitive) {
126
127 searchValue = searchValue.toUpperCase();
128 }
129 if (!createCriteria(example, searchValue, propertyName, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria, formProps )) {
130 throw new RuntimeException("Invalid value in Collection");
131 }
132 }
133 }
134 else {
135 String searchValue = (String) formProps.get(propertyName);
136 if (!caseInsensitive) {
137
138 searchValue = searchValue.toUpperCase();
139 }
140 if (!createCriteria(example, searchValue, propertyName, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria, formProps)) {
141 continue;
142 }
143 }
144 }
145 return criteria;
146 }
147
148 public Criteria getCollectionCriteriaFromMapUsingPrimaryKeysOnly(Class businessObjectClass, Map formProps) {
149 BusinessObject businessObject = checkBusinessObjectClass(businessObjectClass);
150 Criteria criteria = new Criteria();
151 List pkFields = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(businessObjectClass);
152 Iterator pkIter = pkFields.iterator();
153 while (pkIter.hasNext()) {
154 String pkFieldName = (String) pkIter.next();
155 String pkValue = (String) formProps.get(pkFieldName);
156
157 if (StringUtils.isBlank(pkValue)) {
158 throw new RuntimeException("Missing pk value for field " + pkFieldName + " when a search based on PK values only is performed.");
159 }
160 else {
161 for (SearchOperator op : SearchOperator.QUERY_CHARACTERS) {
162 if (pkValue.contains(op.op())) {
163 throw new RuntimeException("Value \"" + pkValue + "\" for PK field " + pkFieldName + " contains wildcard/operator characters.");
164 }
165 }
166 }
167 boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocator.
168 getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(businessObjectClass, pkFieldName);
169 createCriteria(businessObject, pkValue, pkFieldName, false, treatWildcardsAndOperatorsAsLiteral, criteria);
170 }
171 return criteria;
172 }
173
174 private BusinessObject checkBusinessObjectClass(Class businessObjectClass) {
175 if (businessObjectClass == null) {
176 throw new IllegalArgumentException("BusinessObject class passed to LookupDaoOjb findCollectionBySearchHelper... method was null");
177 }
178 BusinessObject businessObject = null;
179 try {
180 businessObject = (BusinessObject) businessObjectClass.newInstance();
181 }
182 catch (IllegalAccessException e) {
183 throw new RuntimeException("LookupDaoOjb could not get instance of " + businessObjectClass.getName(), e);
184 }
185 catch (InstantiationException e) {
186 throw new RuntimeException("LookupDaoOjb could not get instance of " + businessObjectClass.getName(), e);
187 }
188 return businessObject;
189 }
190
191 private Collection executeSearch(Class businessObjectClass, Criteria criteria, boolean unbounded, Integer searchResultsLimit) {
192 Collection searchResults = new ArrayList();
193 Long matchingResultsCount = null;
194 try {
195 if (!unbounded && searchResultsLimit == null) {
196 searchResultsLimit = org.kuali.rice.kns.lookup.LookupUtils.getSearchResultsLimit(businessObjectClass);
197 }
198
199 if (!unbounded && (searchResultsLimit != null) && searchResultsLimit >= 0) {
200 matchingResultsCount = new Long(getPersistenceBrokerTemplate().getCount(QueryFactory.newQuery(businessObjectClass, criteria)));
201 applySearchResultsLimit(businessObjectClass, criteria, getDbPlatform(), searchResultsLimit);
202 }
203 if ((matchingResultsCount == null) || (matchingResultsCount.intValue() <= searchResultsLimit.intValue())) {
204 matchingResultsCount = new Long(0);
205 }
206 searchResults = getPersistenceBrokerTemplate().getCollectionByQuery(QueryFactory.newQuery(businessObjectClass, criteria));
207
208 List bos = new ArrayList();
209 bos.addAll(searchResults);
210 searchResults = bos;
211
212
213 }
214 catch (OjbOperationException e) {
215 throw new RuntimeException("LookupDaoOjb encountered exception during executeSearch", e);
216 }
217 catch (DataIntegrityViolationException e) {
218 throw new RuntimeException("LookupDaoOjb encountered exception during executeSearch", e);
219 }
220 return new CollectionIncomplete(searchResults, matchingResultsCount);
221 }
222
223
224
225
226
227
228
229
230
231
232
233 protected void applySearchResultsLimit(Class businessObjectClass, Criteria criteria, DatabasePlatform platform,
234 Integer limit) {
235 String limitSql = null;
236 if (limit != null) {
237 limitSql = platform.applyLimitSql(limit);
238 } else {
239 limit = LookupUtils.getSearchResultsLimit(businessObjectClass, null);
240 if (limit != null) {
241 limitSql = platform.applyLimitSql(limit);
242 }
243 }
244 if (StringUtils.isNotBlank(limitSql)) {
245 criteria.addSql(limitSql);
246 }
247 }
248
249 public boolean createCriteria(Object example, String searchValue, String propertyName, Object criteria) {
250 return createCriteria( example, searchValue, propertyName, false, false, criteria );
251 }
252
253 public boolean createCriteria(Object example, String searchValue, String propertyName, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Object criteria) {
254 return createCriteria( example, searchValue, propertyName, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria, null );
255 }
256
257 public boolean createCriteria(Object example, String searchValue, String propertyName, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Object criteria, Map searchValues) {
258
259 if (!(criteria instanceof Criteria) || StringUtils.isBlank(searchValue) || !ObjectUtils.isWriteable(example, propertyName, persistenceStructureService)) {
260 return false;
261 }
262
263
264 Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
265 if (propertyType == null) {
266 return false;
267 }
268
269
270 if (example instanceof InactivatableFromTo) {
271 if (KRADPropertyConstants.ACTIVE.equals(propertyName)) {
272 addInactivateableFromToActiveCriteria(example, searchValue, (Criteria) criteria, searchValues);
273 } else if (KRADPropertyConstants.CURRENT.equals(propertyName)) {
274 addInactivateableFromToCurrentCriteria(example, searchValue, (Criteria) criteria, searchValues);
275 } else if (!KRADPropertyConstants.ACTIVE_AS_OF_DATE.equals(propertyName)) {
276 addCriteria(propertyName, searchValue, propertyType, caseInsensitive,
277 treatWildcardsAndOperatorsAsLiteral, (Criteria) criteria);
278 }
279 } else {
280 addCriteria(propertyName, searchValue, propertyType, caseInsensitive, treatWildcardsAndOperatorsAsLiteral,
281 (Criteria) criteria);
282 }
283
284 return true;
285 }
286
287
288
289
290 public Long findCountByMap(Object example, Map formProps) {
291 Criteria criteria = new Criteria();
292
293 Iterator propsIter = formProps.keySet().iterator();
294 while (propsIter.hasNext()) {
295 String propertyName = (String) propsIter.next();
296 String searchValue = (String) formProps.get(propertyName);
297
298
299 if (StringUtils.isBlank(searchValue) || !(PropertyUtils.isWriteable(example, propertyName))) {
300 continue;
301 }
302
303
304 Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
305 if (propertyType == null) {
306 continue;
307 }
308 Boolean caseInsensitive = Boolean.TRUE;
309 if ( KRADServiceLocatorWeb.getDataDictionaryService().isAttributeDefined( example.getClass(), propertyName )) {
310 caseInsensitive = !KRADServiceLocatorWeb.getDataDictionaryService().getAttributeForceUppercase( example.getClass(), propertyName );
311 }
312 if ( caseInsensitive == null ) { caseInsensitive = Boolean.TRUE; }
313
314 boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocator
315 .getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(example.getClass(), propertyName);
316
317 if (!caseInsensitive) {
318
319 searchValue = searchValue.toUpperCase();
320 }
321
322
323 addCriteria(propertyName, searchValue, propertyType, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria);
324 }
325
326
327 Query query = QueryFactory.newQuery(example.getClass(), criteria);
328
329 return new Long(getPersistenceBrokerTemplate().getCount(query));
330 }
331
332
333
334
335 @Override
336 public <T extends Object> T findObjectByMap(Class<T> type, Map<String, String> formProps) {
337 T example = null;
338 try {
339 example = type.newInstance();
340 } catch (IllegalAccessException e) {
341 throw new RuntimeException("Cannot get new instance of " + type.getName(), e);
342 } catch (InstantiationException e) {
343 throw new RuntimeException("Cannot instantiate " + type.getName(), e);
344 }
345
346 if ( KRADServiceLocatorWeb.getLegacyDataAdapter().isPersistable(example.getClass())) {
347 Criteria criteria = new Criteria();
348
349
350 for (Map.Entry<String, String> formProp : formProps.entrySet()) {
351
352 String propertyName = formProp.getKey();
353 String searchValue = "";
354 if (formProp.getValue() != null) {
355 searchValue = formProp.getValue();
356 }
357
358 if (StringUtils.isNotBlank(searchValue) & PropertyUtils.isWriteable(example, propertyName)) {
359 Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
360 if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
361 criteria.addEqualTo(propertyName, cleanNumeric(searchValue));
362 } else if (TypeUtils.isTemporalClass(propertyType)) {
363 criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(searchValue) ) );
364 } else {
365 criteria.addEqualTo(propertyName, searchValue);
366 }
367 }
368 }
369
370
371 Query query = QueryFactory.newQuery(example.getClass(), criteria);
372 return (T)getPersistenceBrokerTemplate().getObjectByQuery(query);
373 }
374 return null;
375 }
376
377
378
379
380
381 private void addCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
382 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.OR.op())) {
383 addOrCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
384 return;
385 }
386
387 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.AND.op())) {
388 addAndCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
389 return;
390 }
391
392 if (StringUtils.equalsIgnoreCase(propertyValue, SearchOperator.NULL.op()) || StringUtils.equalsIgnoreCase(propertyValue, SearchOperator.NOT_NULL.op())) {
393
394 if (StringUtils.contains(propertyValue, SearchOperator.NOT.op())) {
395 criteria.addNotNull(propertyName);
396 }
397 else {
398 criteria.addIsNull(propertyName);
399 }
400 }
401 else if (TypeUtils.isStringClass(propertyType)) {
402
403 if ( caseInsensitive ) {
404 propertyName = getDbPlatform().getUpperCaseFunction() + "(" + propertyName + ")";
405 propertyValue = propertyValue.toUpperCase();
406 }
407 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.NOT.op())) {
408 addNotCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
409 } else if (
410 !treatWildcardsAndOperatorsAsLiteral && propertyValue != null && (
411 StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())
412 || propertyValue.startsWith(">")
413 || propertyValue.startsWith("<") ) ) {
414 addStringRangeCriteria(propertyName, propertyValue, criteria);
415 } else {
416 if (treatWildcardsAndOperatorsAsLiteral) {
417 propertyValue = StringUtils.replace(propertyValue, "*", "\\*");
418 }
419 criteria.addLike(propertyName, propertyValue);
420 }
421 } else if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
422 addNumericRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
423 } else if (TypeUtils.isTemporalClass(propertyType)) {
424 addDateRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
425 } else if (TypeUtils.isBooleanClass(propertyType)) {
426 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
427 } else {
428 LOG.error("not adding criterion for: " + propertyName + "," + propertyType + "," + propertyValue);
429 }
430 }
431
432
433
434
435
436
437
438
439
440 protected void addInactivateableFromToActiveCriteria(Object example, String activeSearchValue, Criteria criteria, Map searchValues) {
441 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
442
443 String activeBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(activeSearchValue);
444 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
445
446 Criteria criteriaBeginDate = new Criteria();
447 criteriaBeginDate.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
448
449 Criteria criteriaBeginDateNull = new Criteria();
450 criteriaBeginDateNull.addIsNull(KRADPropertyConstants.ACTIVE_FROM_DATE);
451 criteriaBeginDate.addOrCriteria(criteriaBeginDateNull);
452
453 criteria.addAndCriteria(criteriaBeginDate);
454
455 Criteria criteriaEndDate = new Criteria();
456 criteriaEndDate.addGreaterThan(KRADPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
457
458 Criteria criteriaEndDateNull = new Criteria();
459 criteriaEndDateNull.addIsNull(KRADPropertyConstants.ACTIVE_TO_DATE);
460 criteriaEndDate.addOrCriteria(criteriaEndDateNull);
461
462 criteria.addAndCriteria(criteriaEndDate);
463 }
464 else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
465
466 Criteria criteriaNonActive = new Criteria();
467 criteriaNonActive.addGreaterThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
468
469 Criteria criteriaEndDate = new Criteria();
470 criteriaEndDate.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
471 criteriaNonActive.addOrCriteria(criteriaEndDate);
472
473 criteria.addAndCriteria(criteriaNonActive);
474 }
475 }
476
477
478
479
480
481
482
483
484 protected void addInactivateableFromToCurrentCriteria(Object example, String currentSearchValue, Criteria criteria, Map searchValues) {
485 Criteria maxBeginDateCriteria = new Criteria();
486
487 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
488
489 maxBeginDateCriteria.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
490
491 List<String> groupByFieldList = dataDictionaryService.getGroupByAttributesForEffectiveDating(example
492 .getClass());
493 if (groupByFieldList == null) {
494 return;
495 }
496
497
498 String[] groupBy = new String[groupByFieldList.size()];
499 for (int i = 0; i < groupByFieldList.size(); i++) {
500 String groupByField = groupByFieldList.get(i);
501 groupBy[i] = groupByField;
502
503 maxBeginDateCriteria.addEqualToField(groupByField, Criteria.PARENT_QUERY_PREFIX + groupByField);
504 }
505
506 String[] columns = new String[1];
507 columns[0] = "max(" + KRADPropertyConstants.ACTIVE_FROM_DATE + ")";
508
509 QueryByCriteria query = QueryFactory.newReportQuery(example.getClass(), columns, maxBeginDateCriteria, true);
510 query.addGroupBy(groupBy);
511
512 String currentBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(currentSearchValue);
513 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
514 criteria.addIn(KRADPropertyConstants.ACTIVE_FROM_DATE, query);
515 } else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
516 criteria.addNotIn(KRADPropertyConstants.ACTIVE_FROM_DATE, query);
517 }
518 }
519
520
521
522
523
524
525
526 private void addOrCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
527 addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, SearchOperator.OR.op());
528 }
529
530
531
532
533
534
535
536 private void addAndCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
537 addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, SearchOperator.AND.op());
538 }
539
540 private void addNotCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
541
542 String[] splitPropVal = StringUtils.split(propertyValue, SearchOperator.NOT.op());
543 try {
544 int strLength = splitPropVal.length;
545
546 if (strLength == 0)
547 throw new IllegalArgumentException("Improper syntax of NOT operator in " + propertyName);
548
549 if (strLength > 1) {
550 String expandedNot = SearchOperator.NOT + StringUtils.join(splitPropVal, SearchOperator.AND.op() + SearchOperator.NOT.op());
551
552 addCriteria(propertyName, expandedNot, propertyType, caseInsensitive, false, criteria);
553 }
554 else {
555
556 criteria.addNotLike(propertyName, splitPropVal[0]);
557 }
558 } catch (IllegalArgumentException ex) {
559 GlobalVariables.getMessageMap().putError("lookupCriteria[" + propertyName + "]", RiceKeyConstants.ERROR_NOT_SYNTAX, propertyName);
560 }
561 }
562
563
564
565
566
567 private void addLogicalOperatorCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria, String splitValue) {
568 String[] splitPropVal = StringUtils.split(propertyValue, splitValue);
569
570 Criteria subCriteria = new Criteria();
571 for (int i = 0; i < splitPropVal.length; i++) {
572 Criteria predicate = new Criteria();
573
574 addCriteria(propertyName, splitPropVal[i], propertyType, caseInsensitive, false, predicate);
575 if (splitValue.equals(SearchOperator.OR.op())) {
576 subCriteria.addOrCriteria(predicate);
577 }
578 if (splitValue.equals(SearchOperator.AND.op())) {
579 subCriteria.addAndCriteria(predicate);
580 }
581 }
582
583 criteria.addAndCriteria(subCriteria);
584 }
585
586 private java.sql.Date parseDate(String dateString) {
587 dateString = dateString.trim();
588 try {
589 return dateTimeService.convertToSqlDate(dateString);
590 } catch (ParseException ex) {
591 return null;
592 }
593 }
594
595
596
597
598 private void addDateRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
599
600 try {
601 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
602 if (treatWildcardsAndOperatorsAsLiteral)
603 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
604 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
605 if (rangeValues.length < 2)
606 throw new IllegalArgumentException("Improper syntax of BETWEEN operator in " + propertyName);
607
608 criteria.addBetween(propertyName, parseDate( ObjectUtils.clean(rangeValues[0] ) ), parseDate( ObjectUtils.clean(rangeValues[1] ) ) );
609 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
610 if (treatWildcardsAndOperatorsAsLiteral)
611 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
612 criteria.addGreaterOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
613 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
614 if (treatWildcardsAndOperatorsAsLiteral)
615 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
616 criteria.addLessOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
617 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
618 if (treatWildcardsAndOperatorsAsLiteral)
619 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
620 criteria.addGreaterThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
621 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
622 if (treatWildcardsAndOperatorsAsLiteral)
623 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
624 criteria.addLessThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
625 } else {
626 criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
627 }
628 } catch (IllegalArgumentException ex) {
629 GlobalVariables.getMessageMap().putError("lookupCriteria[" + propertyName + "]", RiceKeyConstants.ERROR_BETWEEN_SYNTAX, propertyName);
630 }
631 }
632
633 private BigDecimal cleanNumeric( String value ) {
634 String cleanedValue = value.replaceAll( "[^-0-9.]", "" );
635
636 if ( cleanedValue.lastIndexOf( '-' ) > 0 ) {
637 if ( cleanedValue.charAt( 0 ) == '-' ) {
638 cleanedValue = "-" + cleanedValue.replaceAll( "-", "" );
639 } else {
640 cleanedValue = cleanedValue.replaceAll( "-", "" );
641 }
642 }
643
644 int decimalLoc = cleanedValue.lastIndexOf( '.' );
645 if ( cleanedValue.indexOf( '.' ) != decimalLoc ) {
646 cleanedValue = cleanedValue.substring( 0, decimalLoc ).replaceAll( "\\.", "" ) + cleanedValue.substring( decimalLoc );
647 }
648 try {
649 return new BigDecimal( cleanedValue );
650 } catch ( NumberFormatException ex ) {
651 GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_CUSTOM, new String[] { "Invalid Numeric Input: " + value });
652 return null;
653 }
654 }
655
656
657
658
659 private void addNumericRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
660
661 try {
662 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
663 if (treatWildcardsAndOperatorsAsLiteral)
664 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
665 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
666 if (rangeValues.length < 2)
667 throw new IllegalArgumentException("Improper syntax of BETWEEN operator in " + propertyName);
668
669 criteria.addBetween(propertyName, cleanNumeric( rangeValues[0] ), cleanNumeric( rangeValues[1] ));
670 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
671 if (treatWildcardsAndOperatorsAsLiteral)
672 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
673 criteria.addGreaterOrEqualThan(propertyName, cleanNumeric(propertyValue));
674 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
675 if (treatWildcardsAndOperatorsAsLiteral)
676 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
677 criteria.addLessOrEqualThan(propertyName, cleanNumeric(propertyValue));
678 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
679 if (treatWildcardsAndOperatorsAsLiteral)
680 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
681 criteria.addGreaterThan(propertyName, cleanNumeric( propertyValue ) );
682 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
683 if (treatWildcardsAndOperatorsAsLiteral)
684 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
685 criteria.addLessThan(propertyName, cleanNumeric(propertyValue));
686 } else {
687 criteria.addEqualTo(propertyName, cleanNumeric(propertyValue));
688 }
689 } catch (IllegalArgumentException ex) {
690 GlobalVariables.getMessageMap().putError("lookupCriteria[" + propertyName + "]", RiceKeyConstants.ERROR_BETWEEN_SYNTAX, propertyName);
691 }
692 }
693
694
695
696
697 private void addStringRangeCriteria(String propertyName, String propertyValue, Criteria criteria) {
698
699 try {
700 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
701 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
702 if (rangeValues.length < 2)
703 throw new IllegalArgumentException("Improper syntax of BETWEEN operator in " + propertyName);
704
705 criteria.addBetween(propertyName, rangeValues[0], rangeValues[1]);
706 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
707 criteria.addGreaterOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
708 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
709 criteria.addLessOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
710 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
711 criteria.addGreaterThan(propertyName, ObjectUtils.clean(propertyValue));
712 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
713 criteria.addLessThan(propertyName, ObjectUtils.clean(propertyValue));
714 } else {
715 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
716 }
717 } catch (IllegalArgumentException ex) {
718 GlobalVariables.getMessageMap().putError("lookupCriteria[" + propertyName + "]", RiceKeyConstants.ERROR_BETWEEN_SYNTAX, propertyName);
719 }
720 }
721
722 public void setDateTimeService(DateTimeService dateTimeService) {
723 this.dateTimeService = dateTimeService;
724 }
725
726 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
727 this.persistenceStructureService = persistenceStructureService;
728 }
729
730 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
731 this.dataDictionaryService = dataDictionaryService;
732 }
733 }