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, false, false, 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 if (StringUtils.contains(propertyValue, SearchOperator.NOT.op())) {
329 criteria.addColumnNotNull(propertyName);
330 }
331 else {
332 criteria.addColumnIsNull(propertyName);
333 }
334 }
335 else if (TypeUtils.isStringClass(propertyType)) {
336
337 if ( caseInsensitive ) {
338 propertyName = getDbPlatform().getUpperCaseFunction() + "(" + propertyName + ")";
339 propertyValue = propertyValue.toUpperCase();
340 }
341 if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, SearchOperator.NOT.op())) {
342 addNotCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
343 } else if (
344 !treatWildcardsAndOperatorsAsLiteral && propertyValue != null && (
345 StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())
346 || propertyValue.startsWith(">")
347 || propertyValue.startsWith("<") ) ) {
348 addStringRangeCriteria(propertyName, propertyValue, criteria);
349 } else {
350 if (treatWildcardsAndOperatorsAsLiteral) {
351 propertyValue = StringUtils.replace(propertyValue, "*", "\\*");
352 }
353 criteria.addLike(propertyName, propertyValue);
354 }
355 } else if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
356 addNumericRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
357 } else if (TypeUtils.isTemporalClass(propertyType)) {
358 addDateRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
359 } else if (TypeUtils.isBooleanClass(propertyType)) {
360 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
361 } else {
362 LOG.error("not adding criterion for: " + propertyName + "," + propertyType + "," + propertyValue);
363 }
364 }
365
366
367
368
369
370
371
372
373
374 protected void addInactivateableFromToActiveCriteria(Object example, String activeSearchValue, Criteria criteria, Map searchValues) {
375 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
376
377 String activeBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(activeSearchValue);
378 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
379
380 Criteria criteriaBeginDate = new Criteria();
381 criteriaBeginDate.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
382
383 Criteria criteriaBeginDateNull = new Criteria();
384 criteriaBeginDateNull.addIsNull(KRADPropertyConstants.ACTIVE_FROM_DATE);
385 criteriaBeginDate.addOrCriteria(criteriaBeginDateNull);
386
387 criteria.addAndCriteria(criteriaBeginDate);
388
389 Criteria criteriaEndDate = new Criteria();
390 criteriaEndDate.addGreaterThan(KRADPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
391
392 Criteria criteriaEndDateNull = new Criteria();
393 criteriaEndDateNull.addIsNull(KRADPropertyConstants.ACTIVE_TO_DATE);
394 criteriaEndDate.addOrCriteria(criteriaEndDateNull);
395
396 criteria.addAndCriteria(criteriaEndDate);
397 }
398 else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
399
400 Criteria criteriaNonActive = new Criteria();
401 criteriaNonActive.addGreaterThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
402
403 Criteria criteriaEndDate = new Criteria();
404 criteriaEndDate.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
405 criteriaNonActive.addOrCriteria(criteriaEndDate);
406
407 criteria.addAndCriteria(criteriaNonActive);
408 }
409 }
410
411
412
413
414
415
416
417
418 protected void addInactivateableFromToCurrentCriteria(Object example, String currentSearchValue, Criteria criteria, Map searchValues) {
419 Criteria maxBeginDateCriteria = new Criteria();
420
421 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
422
423 maxBeginDateCriteria.addLessOrEqualThan(KRADPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
424
425 List<String> groupByFieldList = dataDictionaryService.getGroupByAttributesForEffectiveDating(example
426 .getClass());
427 if (groupByFieldList == null) {
428 return;
429 }
430
431
432 String[] groupBy = new String[groupByFieldList.size()];
433 for (int i = 0; i < groupByFieldList.size(); i++) {
434 String groupByField = groupByFieldList.get(i);
435 groupBy[i] = groupByField;
436
437 maxBeginDateCriteria.addEqualToField(groupByField, Criteria.PARENT_QUERY_PREFIX + groupByField);
438 }
439
440 String[] columns = new String[1];
441 columns[0] = "max(" + KRADPropertyConstants.ACTIVE_FROM_DATE + ")";
442
443 QueryByCriteria query = QueryFactory.newReportQuery(example.getClass(), columns, maxBeginDateCriteria, true);
444 query.addGroupBy(groupBy);
445
446 String currentBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(currentSearchValue);
447 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
448 criteria.addIn(KRADPropertyConstants.ACTIVE_FROM_DATE, query);
449 } else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
450 criteria.addNotIn(KRADPropertyConstants.ACTIVE_FROM_DATE, query);
451 }
452 }
453
454
455
456
457
458
459
460 private void addOrCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
461 addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, SearchOperator.OR.op());
462 }
463
464
465
466
467
468
469
470 private void addAndCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
471 addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, SearchOperator.AND.op());
472 }
473
474 private void addNotCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
475
476 String[] splitPropVal = StringUtils.split(propertyValue, SearchOperator.NOT.op());
477
478 int strLength = splitPropVal.length;
479
480 if (strLength > 1) {
481 String expandedNot = SearchOperator.NOT + StringUtils.join(splitPropVal, SearchOperator.AND.op() + SearchOperator.NOT.op());
482
483 addCriteria(propertyName, expandedNot, propertyType, caseInsensitive, false, criteria);
484 }
485 else {
486
487 criteria.addNotLike(propertyName, splitPropVal[0]);
488 }
489 }
490
491
492
493
494
495 private void addLogicalOperatorCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria, String splitValue) {
496 String[] splitPropVal = StringUtils.split(propertyValue, splitValue);
497
498 Criteria subCriteria = new Criteria();
499 for (int i = 0; i < splitPropVal.length; i++) {
500 Criteria predicate = new Criteria();
501
502 addCriteria(propertyName, splitPropVal[i], propertyType, caseInsensitive, false, predicate);
503 if (splitValue.equals(SearchOperator.OR.op())) {
504 subCriteria.addOrCriteria(predicate);
505 }
506 if (splitValue.equals(SearchOperator.AND.op())) {
507 subCriteria.addAndCriteria(predicate);
508 }
509 }
510
511 criteria.addAndCriteria(subCriteria);
512 }
513
514 private java.sql.Date parseDate(String dateString) {
515 dateString = dateString.trim();
516 try {
517 return dateTimeService.convertToSqlDate(dateString);
518 } catch (ParseException ex) {
519 return null;
520 }
521 }
522
523
524
525
526 private void addDateRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
527
528 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
529 if (treatWildcardsAndOperatorsAsLiteral)
530 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
531 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
532 criteria.addBetween(propertyName, parseDate( ObjectUtils.clean(rangeValues[0] ) ), parseDate( ObjectUtils.clean(rangeValues[1] ) ) );
533 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
534 if (treatWildcardsAndOperatorsAsLiteral)
535 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
536 criteria.addGreaterOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
537 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
538 if (treatWildcardsAndOperatorsAsLiteral)
539 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
540 criteria.addLessOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
541 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
542 if (treatWildcardsAndOperatorsAsLiteral)
543 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
544 criteria.addGreaterThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
545 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
546 if (treatWildcardsAndOperatorsAsLiteral)
547 throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
548 criteria.addLessThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
549 } else {
550 criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
551 }
552 }
553
554 private BigDecimal cleanNumeric( String value ) {
555 String cleanedValue = value.replaceAll( "[^-0-9.]", "" );
556
557 if ( cleanedValue.lastIndexOf( '-' ) > 0 ) {
558 if ( cleanedValue.charAt( 0 ) == '-' ) {
559 cleanedValue = "-" + cleanedValue.replaceAll( "-", "" );
560 } else {
561 cleanedValue = cleanedValue.replaceAll( "-", "" );
562 }
563 }
564
565 int decimalLoc = cleanedValue.lastIndexOf( '.' );
566 if ( cleanedValue.indexOf( '.' ) != decimalLoc ) {
567 cleanedValue = cleanedValue.substring( 0, decimalLoc ).replaceAll( "\\.", "" ) + cleanedValue.substring( decimalLoc );
568 }
569 try {
570 return new BigDecimal( cleanedValue );
571 } catch ( NumberFormatException ex ) {
572 GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_CUSTOM, new String[] { "Invalid Numeric Input: " + value });
573 return null;
574 }
575 }
576
577
578
579
580 private void addNumericRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
581
582 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
583 if (treatWildcardsAndOperatorsAsLiteral)
584 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
585 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
586 criteria.addBetween(propertyName, cleanNumeric( rangeValues[0] ), cleanNumeric( rangeValues[1] ));
587 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
588 if (treatWildcardsAndOperatorsAsLiteral)
589 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
590 criteria.addGreaterOrEqualThan(propertyName, cleanNumeric(propertyValue));
591 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
592 if (treatWildcardsAndOperatorsAsLiteral)
593 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
594 criteria.addLessOrEqualThan(propertyName, cleanNumeric(propertyValue));
595 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
596 if (treatWildcardsAndOperatorsAsLiteral)
597 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
598 criteria.addGreaterThan(propertyName, cleanNumeric( propertyValue ) );
599 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
600 if (treatWildcardsAndOperatorsAsLiteral)
601 throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
602 criteria.addLessThan(propertyName, cleanNumeric(propertyValue));
603 } else {
604 criteria.addEqualTo(propertyName, cleanNumeric(propertyValue));
605 }
606 }
607
608
609
610
611 private void addStringRangeCriteria(String propertyName, String propertyValue, Criteria criteria) {
612
613 if (StringUtils.contains(propertyValue, SearchOperator.BETWEEN.op())) {
614 String[] rangeValues = StringUtils.split(propertyValue, SearchOperator.BETWEEN.op());
615 criteria.addBetween(propertyName, rangeValues[0], rangeValues[1]);
616 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN_EQUAL.op())) {
617 criteria.addGreaterOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
618 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN_EQUAL.op())) {
619 criteria.addLessOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
620 } else if (propertyValue.startsWith(SearchOperator.GREATER_THAN.op())) {
621 criteria.addGreaterThan(propertyName, ObjectUtils.clean(propertyValue));
622 } else if (propertyValue.startsWith(SearchOperator.LESS_THAN.op())) {
623 criteria.addLessThan(propertyName, ObjectUtils.clean(propertyValue));
624 } else {
625 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
626 }
627 }
628
629 public void setDateTimeService(DateTimeService dateTimeService) {
630 this.dateTimeService = dateTimeService;
631 }
632
633 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
634 this.persistenceStructureService = persistenceStructureService;
635 }
636
637 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
638 this.dataDictionaryService = dataDictionaryService;
639 }
640 }