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 catch (OjbOperationException e) {
185 throw new RuntimeException("LookupDaoOjb encountered exception during executeSearch", e);
186 }
187 catch (DataIntegrityViolationException e) {
188 throw new RuntimeException("LookupDaoOjb encountered exception during executeSearch", e);
189 }
190 return new CollectionIncomplete(searchResults, matchingResultsCount);
191 }
192
193 public boolean createCriteria(Object example, String searchValue, String propertyName, Object criteria) {
194 return createCriteria( example, searchValue, propertyName, false, false, criteria );
195 }
196
197 public boolean createCriteria(Object example, String searchValue, String propertyName, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Object criteria) {
198 return createCriteria( example, searchValue, propertyName, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria, null );
199 }
200
201 public boolean createCriteria(Object example, String searchValue, String propertyName, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Object criteria, Map searchValues) {
202
203 if (!(criteria instanceof Criteria) || StringUtils.isBlank(searchValue) || !ObjectUtils.isWriteable(example, propertyName, persistenceStructureService)) {
204 return false;
205 }
206
207
208 Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
209 if (propertyType == null) {
210 return false;
211 }
212
213
214 if (example instanceof InactivatableFromTo) {
215 if (KRADPropertyConstants.ACTIVE.equals(propertyName)) {
216 addInactivateableFromToActiveCriteria(example, searchValue, (Criteria) criteria, searchValues);
217 } else if (KRADPropertyConstants.CURRENT.equals(propertyName)) {
218 addInactivateableFromToCurrentCriteria(example, searchValue, (Criteria) criteria, searchValues);
219 } else if (!KRADPropertyConstants.ACTIVE_AS_OF_DATE.equals(propertyName)) {
220 addCriteria(propertyName, searchValue, propertyType, caseInsensitive,
221 treatWildcardsAndOperatorsAsLiteral, (Criteria) criteria);
222 }
223 } else {
224 addCriteria(propertyName, searchValue, propertyType, caseInsensitive, treatWildcardsAndOperatorsAsLiteral,
225 (Criteria) criteria);
226 }
227
228 return true;
229 }
230
231
232
233
234 public Long findCountByMap(Object example, Map formProps) {
235 Criteria criteria = new Criteria();
236
237 Iterator propsIter = formProps.keySet().iterator();
238 while (propsIter.hasNext()) {
239 String propertyName = (String) propsIter.next();
240 String searchValue = (String) formProps.get(propertyName);
241
242
243 if (StringUtils.isBlank(searchValue) || !(PropertyUtils.isWriteable(example, propertyName))) {
244 continue;
245 }
246
247
248 Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
249 if (propertyType == null) {
250 continue;
251 }
252 Boolean caseInsensitive = Boolean.TRUE;
253 if ( KRADServiceLocatorWeb.getDataDictionaryService().isAttributeDefined( example.getClass(), propertyName )) {
254 caseInsensitive = !KRADServiceLocatorWeb.getDataDictionaryService().getAttributeForceUppercase( example.getClass(), propertyName );
255 }
256 if ( caseInsensitive == null ) { caseInsensitive = Boolean.TRUE; }
257
258 boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocator
259 .getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(example.getClass(), propertyName);
260
261 if (!caseInsensitive) {
262
263 searchValue = searchValue.toUpperCase();
264 }
265
266
267 addCriteria(propertyName, searchValue, propertyType, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria);
268 }
269
270
271 Query query = QueryFactory.newQuery(example.getClass(), criteria);
272
273 return new Long(getPersistenceBrokerTemplate().getCount(query));
274 }
275
276
277
278
279 @Override
280 public <T extends Object> T findObjectByMap(T example, Map<String, String> formProps) {
281 if ( persistenceStructureService.isPersistable(example.getClass())) {
282 Criteria criteria = new Criteria();
283
284
285 for (Map.Entry<String, String> formProp : formProps.entrySet()) {
286
287 String propertyName = formProp.getKey();
288 String searchValue = "";
289 if (formProp.getValue() != null) {
290 searchValue = formProp.getValue();
291 }
292
293 if (StringUtils.isNotBlank(searchValue) & PropertyUtils.isWriteable(example, propertyName)) {
294 Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
295 if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
296 criteria.addEqualTo(propertyName, cleanNumeric(searchValue));
297 } else if (TypeUtils.isTemporalClass(propertyType)) {
298 criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(searchValue) ) );
299 } else {
300 criteria.addEqualTo(propertyName, searchValue);
301 }
302 }
303 }
304
305
306 Query query = QueryFactory.newQuery(example.getClass(), criteria);
307 return (T)getPersistenceBrokerTemplate().getObjectByQuery(query);
308 }
309 return null;
310 }
311
312
313
314
315
316 private void addCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
317 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.OR.op())) {
318 addOrCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
319 return;
320 }
321
322 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.AND.op())) {
323 addAndCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
324 return;
325 }
326
327 if (StringUtils.equalsIgnoreCase(propertyValue, SearchOperator.NULL.op()) || StringUtils.equalsIgnoreCase(propertyValue, SearchOperator.NOT_NULL.op())) {
328
329 if (StringUtils.contains(propertyValue, SearchOperator.NOT.op())) {
330 criteria.addNotNull(propertyName);
331 }
332 else {
333 criteria.addIsNull(propertyName);
334 }
335 }
336 else if (TypeUtils.isStringClass(propertyType)) {
337
338 if ( caseInsensitive ) {
339 propertyName = getDbPlatform().getUpperCaseFunction() + "(" + propertyName + ")";
340 propertyValue = propertyValue.toUpperCase();
341 }
342 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.NOT.op())) {
343 addNotCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
344 } else if (
345 !treatWildcardsAndOperatorsAsLiteral && propertyValue != null && (
346 StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())
347 || propertyValue.startsWith(">")
348 || propertyValue.startsWith("<") ) ) {
349 addStringRangeCriteria(propertyName, propertyValue, criteria);
350 } else {
351 if (treatWildcardsAndOperatorsAsLiteral) {
352 propertyValue = StringUtils.replace(propertyValue, "*", "\\*");
353 }
354 criteria.addLike(propertyName, propertyValue);
355 }
356 } else if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
357 addNumericRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
358 } else if (TypeUtils.isTemporalClass(propertyType)) {
359 addDateRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
360 } else if (TypeUtils.isBooleanClass(propertyType)) {
361 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
362 } else {
363 LOG.error("not adding criterion for: " + propertyName + "," + propertyType + "," + propertyValue);
364 }
365 }
366
367
368
369
370
371
372
373
374
375 protected void addInactivateableFromToActiveCriteria(Object example, String activeSearchValue, Criteria criteria, Map searchValues) {
376 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
377
378 String activeBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(activeSearchValue);
379 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
380
381 Criteria criteriaBeginDate = new Criteria();
382 criteriaBeginDate.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
383
384 Criteria criteriaBeginDateNull = new Criteria();
385 criteriaBeginDateNull.addIsNull(KRADPropertyConstants.ACTIVE_FROM_DATE);
386 criteriaBeginDate.addOrCriteria(criteriaBeginDateNull);
387
388 criteria.addAndCriteria(criteriaBeginDate);
389
390 Criteria criteriaEndDate = new Criteria();
391 criteriaEndDate.addGreaterThan(KRADPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
392
393 Criteria criteriaEndDateNull = new Criteria();
394 criteriaEndDateNull.addIsNull(KRADPropertyConstants.ACTIVE_TO_DATE);
395 criteriaEndDate.addOrCriteria(criteriaEndDateNull);
396
397 criteria.addAndCriteria(criteriaEndDate);
398 }
399 else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
400
401 Criteria criteriaNonActive = new Criteria();
402 criteriaNonActive.addGreaterThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
403
404 Criteria criteriaEndDate = new Criteria();
405 criteriaEndDate.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
406 criteriaNonActive.addOrCriteria(criteriaEndDate);
407
408 criteria.addAndCriteria(criteriaNonActive);
409 }
410 }
411
412
413
414
415
416
417
418
419 protected void addInactivateableFromToCurrentCriteria(Object example, String currentSearchValue, Criteria criteria, Map searchValues) {
420 Criteria maxBeginDateCriteria = new Criteria();
421
422 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
423
424 maxBeginDateCriteria.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
425
426 List<String> groupByFieldList = dataDictionaryService.getGroupByAttributesForEffectiveDating(example
427 .getClass());
428 if (groupByFieldList == null) {
429 return;
430 }
431
432
433 String[] groupBy = new String[groupByFieldList.size()];
434 for (int i = 0; i < groupByFieldList.size(); i++) {
435 String groupByField = groupByFieldList.get(i);
436 groupBy[i] = groupByField;
437
438 maxBeginDateCriteria.addEqualToField(groupByField, Criteria.PARENT_QUERY_PREFIX + groupByField);
439 }
440
441 String[] columns = new String[1];
442 columns[0] = "max(" + KRADPropertyConstants.ACTIVE_FROM_DATE + ")";
443
444 QueryByCriteria query = QueryFactory.newReportQuery(example.getClass(), columns, maxBeginDateCriteria, true);
445 query.addGroupBy(groupBy);
446
447 String currentBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(currentSearchValue);
448 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
449 criteria.addIn(KRADPropertyConstants.ACTIVE_FROM_DATE, query);
450 } else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
451 criteria.addNotIn(KRADPropertyConstants.ACTIVE_FROM_DATE, query);
452 }
453 }
454
455
456
457
458
459
460
461 private void addOrCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
462 addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, SearchOperator.OR.op());
463 }
464
465
466
467
468
469
470
471 private void addAndCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
472 addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, SearchOperator.AND.op());
473 }
474
475 private void addNotCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
476
477 String[] splitPropVal = StringUtils.split(propertyValue, SearchOperator.NOT.op());
478
479 int strLength = splitPropVal.length;
480
481 if (strLength > 1) {
482 String expandedNot = SearchOperator.NOT + StringUtils.join(splitPropVal, SearchOperator.AND.op() + SearchOperator.NOT.op());
483
484 addCriteria(propertyName, expandedNot, propertyType, caseInsensitive, false, criteria);
485 }
486 else {
487
488 criteria.addNotLike(propertyName, splitPropVal[0]);
489 }
490 }
491
492
493
494
495
496 private void addLogicalOperatorCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria, String splitValue) {
497 String[] splitPropVal = StringUtils.split(propertyValue, splitValue);
498
499 Criteria subCriteria = new Criteria();
500 for (int i = 0; i < splitPropVal.length; i++) {
501 Criteria predicate = new Criteria();
502
503 addCriteria(propertyName, splitPropVal[i], propertyType, caseInsensitive, false, predicate);
504 if (splitValue.equals(SearchOperator.OR.op())) {
505 subCriteria.addOrCriteria(predicate);
506 }
507 if (splitValue.equals(SearchOperator.AND.op())) {
508 subCriteria.addAndCriteria(predicate);
509 }
510 }
511
512 criteria.addAndCriteria(subCriteria);
513 }
514
515 private java.sql.Date parseDate(String dateString) {
516 dateString = dateString.trim();
517 try {
518 return dateTimeService.convertToSqlDate(dateString);
519 } catch (ParseException ex) {
520 return null;
521 }
522 }
523
524
525
526
527 private void addDateRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
528
529 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
530 if (treatWildcardsAndOperatorsAsLiteral)
531 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
532 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
533 criteria.addBetween(propertyName, parseDate( ObjectUtils.clean(rangeValues[0] ) ), parseDate( ObjectUtils.clean(rangeValues[1] ) ) );
534 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
535 if (treatWildcardsAndOperatorsAsLiteral)
536 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
537 criteria.addGreaterOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
538 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
539 if (treatWildcardsAndOperatorsAsLiteral)
540 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
541 criteria.addLessOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
542 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
543 if (treatWildcardsAndOperatorsAsLiteral)
544 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
545 criteria.addGreaterThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
546 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
547 if (treatWildcardsAndOperatorsAsLiteral)
548 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
549 criteria.addLessThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
550 } else {
551 criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
552 }
553 }
554
555 private BigDecimal cleanNumeric( String value ) {
556 String cleanedValue = value.replaceAll( "[^-0-9.]", "" );
557
558 if ( cleanedValue.lastIndexOf( '-' ) > 0 ) {
559 if ( cleanedValue.charAt( 0 ) == '-' ) {
560 cleanedValue = "-" + cleanedValue.replaceAll( "-", "" );
561 } else {
562 cleanedValue = cleanedValue.replaceAll( "-", "" );
563 }
564 }
565
566 int decimalLoc = cleanedValue.lastIndexOf( '.' );
567 if ( cleanedValue.indexOf( '.' ) != decimalLoc ) {
568 cleanedValue = cleanedValue.substring( 0, decimalLoc ).replaceAll( "\\.", "" ) + cleanedValue.substring( decimalLoc );
569 }
570 try {
571 return new BigDecimal( cleanedValue );
572 } catch ( NumberFormatException ex ) {
573 GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_CUSTOM, new String[] { "Invalid Numeric Input: " + value });
574 return null;
575 }
576 }
577
578
579
580
581 private void addNumericRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
582
583 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
584 if (treatWildcardsAndOperatorsAsLiteral)
585 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
586 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
587 criteria.addBetween(propertyName, cleanNumeric( rangeValues[0] ), cleanNumeric( rangeValues[1] ));
588 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
589 if (treatWildcardsAndOperatorsAsLiteral)
590 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
591 criteria.addGreaterOrEqualThan(propertyName, cleanNumeric(propertyValue));
592 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
593 if (treatWildcardsAndOperatorsAsLiteral)
594 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
595 criteria.addLessOrEqualThan(propertyName, cleanNumeric(propertyValue));
596 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
597 if (treatWildcardsAndOperatorsAsLiteral)
598 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
599 criteria.addGreaterThan(propertyName, cleanNumeric( propertyValue ) );
600 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
601 if (treatWildcardsAndOperatorsAsLiteral)
602 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
603 criteria.addLessThan(propertyName, cleanNumeric(propertyValue));
604 } else {
605 criteria.addEqualTo(propertyName, cleanNumeric(propertyValue));
606 }
607 }
608
609
610
611
612 private void addStringRangeCriteria(String propertyName, String propertyValue, Criteria criteria) {
613
614 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
615 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
616 criteria.addBetween(propertyName, rangeValues[0], rangeValues[1]);
617 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
618 criteria.addGreaterOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
619 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
620 criteria.addLessOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
621 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
622 criteria.addGreaterThan(propertyName, ObjectUtils.clean(propertyValue));
623 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
624 criteria.addLessThan(propertyName, ObjectUtils.clean(propertyValue));
625 } else {
626 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
627 }
628 }
629
630 public void setDateTimeService(DateTimeService dateTimeService) {
631 this.dateTimeService = dateTimeService;
632 }
633
634 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
635 this.persistenceStructureService = persistenceStructureService;
636 }
637
638 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
639 this.dataDictionaryService = dataDictionaryService;
640 }
641 }