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