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