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