Coverage Report - org.kuali.rice.kns.dao.impl.LookupDaoOjb
 
Classes in this File Line Coverage Branch Coverage Complexity
LookupDaoOjb
0%
0/304
0%
0/198
6
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kns.dao.impl;
 17  
 
 18  
 import java.math.BigDecimal;
 19  
 import java.sql.Timestamp;
 20  
 import java.text.ParseException;
 21  
 import java.util.ArrayList;
 22  
 import java.util.Collection;
 23  
 import java.util.Iterator;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 
 27  
 import org.apache.commons.beanutils.PropertyUtils;
 28  
 import org.apache.commons.lang.StringUtils;
 29  
 import org.apache.ojb.broker.query.Criteria;
 30  
 import org.apache.ojb.broker.query.Query;
 31  
 import org.apache.ojb.broker.query.QueryByCriteria;
 32  
 import org.apache.ojb.broker.query.QueryFactory;
 33  
 import org.kuali.rice.core.api.datetime.DateTimeService;
 34  
 import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
 35  
 import org.kuali.rice.core.util.RiceKeyConstants;
 36  
 import org.kuali.rice.core.util.type.TypeUtils;
 37  
 import org.kuali.rice.kns.bo.BusinessObject;
 38  
 import org.kuali.rice.kns.bo.InactivateableFromTo;
 39  
 import org.kuali.rice.kns.dao.LookupDao;
 40  
 import org.kuali.rice.kns.lookup.CollectionIncomplete;
 41  
 import org.kuali.rice.kns.lookup.LookupUtils;
 42  
 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
 43  
 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
 44  
 import org.kuali.rice.kns.service.PersistenceStructureService;
 45  
 import org.kuali.rice.kns.util.GlobalVariables;
 46  
 import org.kuali.rice.kns.util.KNSConstants;
 47  
 import org.kuali.rice.kns.util.KNSPropertyConstants;
 48  
 import org.kuali.rice.kns.util.ObjectUtils;
 49  
 import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbCharBooleanConversion;
 50  
 import org.springframework.dao.DataIntegrityViolationException;
 51  
 import org.springmodules.orm.ojb.OjbOperationException;
 52  
 
 53  
 /**
 54  
  * OJB implementation of the LookupDao interface
 55  
  */
 56  0
 public class LookupDaoOjb extends PlatformAwareDaoBaseOjb implements LookupDao {
 57  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LookupDaoOjb.class);
 58  
     private DateTimeService dateTimeService;
 59  
     private PersistenceStructureService persistenceStructureService;
 60  
     private BusinessObjectDictionaryService businessObjectDictionaryService;
 61  
 
 62  
     public Collection findCollectionBySearchHelper(Class businessObjectClass, Map formProps, boolean unbounded, boolean usePrimaryKeyValuesOnly) {
 63  0
         return findCollectionBySearchHelper( businessObjectClass, formProps, unbounded, usePrimaryKeyValuesOnly, null );
 64  
     }
 65  
 
 66  
     public Collection findCollectionBySearchHelper(Class businessObjectClass, Map formProps, boolean unbounded, boolean usePrimaryKeyValuesOnly, Object additionalCriteria ) {
 67  0
         BusinessObject businessObject = checkBusinessObjectClass(businessObjectClass);
 68  0
         if (usePrimaryKeyValuesOnly) {
 69  0
                 return executeSearch(businessObjectClass, getCollectionCriteriaFromMapUsingPrimaryKeysOnly(businessObjectClass, formProps), unbounded);
 70  
         }
 71  
         
 72  0
                 Criteria crit = getCollectionCriteriaFromMap(businessObject, formProps);
 73  0
                 if (additionalCriteria != null && additionalCriteria instanceof Criteria) {
 74  0
                         crit.addAndCriteria((Criteria) additionalCriteria);
 75  
                 }
 76  
 
 77  0
                 return executeSearch(businessObjectClass, crit, unbounded);
 78  
         }
 79  
 
 80  
     /**
 81  
      * Builds up criteria object based on the object and map.
 82  
      */
 83  
     public Criteria getCollectionCriteriaFromMap(BusinessObject example, Map formProps) {
 84  0
         Criteria criteria = new Criteria();
 85  0
         Iterator propsIter = formProps.keySet().iterator();
 86  0
         while (propsIter.hasNext()) {
 87  0
             String propertyName = (String) propsIter.next();
 88  0
             Boolean caseInsensitive = Boolean.TRUE;
 89  0
                 if ( KNSServiceLocatorWeb.getDataDictionaryService().isAttributeDefined( example.getClass(), propertyName )) {
 90  0
                         caseInsensitive = !KNSServiceLocatorWeb.getDataDictionaryService().getAttributeForceUppercase( example.getClass(), propertyName );
 91  
                 }
 92  0
                 if ( caseInsensitive == null ) { caseInsensitive = Boolean.TRUE; }
 93  0
                 boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocatorWeb
 94  
                                 .getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(example.getClass(), propertyName);
 95  
                 
 96  0
             if (formProps.get(propertyName) instanceof Collection) {
 97  0
                 Iterator iter = ((Collection) formProps.get(propertyName)).iterator();
 98  0
                 while (iter.hasNext()) {
 99  0
                     if (!createCriteria(example, (String) iter.next(), propertyName, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria, formProps )) {
 100  0
                         throw new RuntimeException("Invalid value in Collection");
 101  
                     }
 102  
                 }
 103  0
             }
 104  
             else {
 105  0
                 if (!createCriteria(example, (String) formProps.get(propertyName), propertyName, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria, formProps)) {
 106  0
                     continue;
 107  
                 }
 108  
             }
 109  0
         }
 110  0
         return criteria;
 111  
     }
 112  
     
 113  
     public Criteria getCollectionCriteriaFromMapUsingPrimaryKeysOnly(Class businessObjectClass, Map formProps) {
 114  0
         BusinessObject businessObject = checkBusinessObjectClass(businessObjectClass);
 115  0
         Criteria criteria = new Criteria();
 116  0
         List pkFields = KNSServiceLocatorWeb.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(businessObjectClass);
 117  0
         Iterator pkIter = pkFields.iterator();
 118  0
         while (pkIter.hasNext()) {
 119  0
             String pkFieldName = (String) pkIter.next();
 120  0
             String pkValue = (String) formProps.get(pkFieldName);
 121  
 
 122  0
             if (StringUtils.isBlank(pkValue)) {
 123  0
                 throw new RuntimeException("Missing pk value for field " + pkFieldName + " when a search based on PK values only is performed.");
 124  
             }
 125  0
             else if (StringUtils.indexOfAny(pkValue, KNSConstants.QUERY_CHARACTERS) != -1) {
 126  0
                 throw new RuntimeException("Value \"" + pkValue + "\" for PK field " + pkFieldName + " contains wildcard/operator characters.");
 127  
             }
 128  0
             boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocatorWeb.
 129  
                             getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(businessObjectClass, pkFieldName);
 130  0
             createCriteria(businessObject, pkValue, pkFieldName, false, treatWildcardsAndOperatorsAsLiteral, criteria);
 131  0
         }
 132  0
         return criteria;
 133  
     }
 134  
     
 135  
     private BusinessObject checkBusinessObjectClass(Class businessObjectClass) {
 136  0
         if (businessObjectClass == null) {
 137  0
             throw new IllegalArgumentException("BusinessObject class passed to LookupDaoOjb findCollectionBySearchHelper... method was null");
 138  
         }
 139  0
         BusinessObject businessObject = null;
 140  
         try {
 141  0
             businessObject = (BusinessObject) businessObjectClass.newInstance();
 142  
         }
 143  0
         catch (IllegalAccessException e) {
 144  0
             throw new RuntimeException("LookupDaoOjb could not get instance of " + businessObjectClass.getName(), e);
 145  
         }
 146  0
         catch (InstantiationException e) {
 147  0
             throw new RuntimeException("LookupDaoOjb could not get instance of " + businessObjectClass.getName(), e);
 148  0
         }
 149  0
         return businessObject;
 150  
     }
 151  
 
 152  
     private Collection executeSearch(Class businessObjectClass, Criteria criteria, boolean unbounded) {
 153  0
             Collection searchResults = new ArrayList();
 154  0
             Long matchingResultsCount = null;
 155  
             try {
 156  0
                     Integer searchResultsLimit = LookupUtils.getSearchResultsLimit(businessObjectClass);
 157  0
                     if (!unbounded && (searchResultsLimit != null)) {
 158  0
                             matchingResultsCount = new Long(getPersistenceBrokerTemplate().getCount(QueryFactory.newQuery(businessObjectClass, criteria)));
 159  0
                             LookupUtils.applySearchResultsLimit(businessObjectClass, criteria, getDbPlatform());
 160  
                     }
 161  0
                     if ((matchingResultsCount == null) || (matchingResultsCount.intValue() <= searchResultsLimit.intValue())) {
 162  0
                             matchingResultsCount = new Long(0);
 163  
                     }
 164  0
                     searchResults = getPersistenceBrokerTemplate().getCollectionByQuery(QueryFactory.newQuery(businessObjectClass, criteria));
 165  
                     // populate Person objects in business objects
 166  0
                     List bos = new ArrayList();
 167  0
                     bos.addAll(searchResults);
 168  0
                     searchResults = bos;
 169  
             }
 170  0
             catch (OjbOperationException e) {
 171  0
                     throw new RuntimeException("LookupDaoOjb encountered exception during executeSearch", e);
 172  
             }
 173  0
             catch (DataIntegrityViolationException e) {
 174  0
                     throw new RuntimeException("LookupDaoOjb encountered exception during executeSearch", e);
 175  0
             }
 176  0
             return new CollectionIncomplete(searchResults, matchingResultsCount);
 177  
     }
 178  
 
 179  
     public boolean createCriteria(Object example, String searchValue, String propertyName, Object criteria) {
 180  0
             return createCriteria( example, searchValue, propertyName, false, false, criteria );
 181  
     }
 182  
     
 183  
     public boolean createCriteria(Object example, String searchValue, String propertyName, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Object criteria) {
 184  0
             return createCriteria( example, searchValue, propertyName, false, false, criteria, null );
 185  
     }
 186  
 
 187  
     public boolean createCriteria(Object example, String searchValue, String propertyName, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Object criteria, Map searchValues) {
 188  
         // if searchValue is empty and the key is not a valid property ignore
 189  0
         if (!(criteria instanceof Criteria) || StringUtils.isBlank(searchValue) || !ObjectUtils.isWriteable(example, propertyName, persistenceStructureService)) {
 190  0
             return false;
 191  
         }
 192  
 
 193  
         // get property type which is used to determine type of criteria
 194  0
         Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
 195  0
         if (propertyType == null) {
 196  0
             return false;
 197  
         }
 198  
 
 199  
                 // build criteria
 200  0
                 if (example instanceof InactivateableFromTo) {
 201  0
                         if (KNSPropertyConstants.ACTIVE.equals(propertyName)) {
 202  0
                                 addInactivateableFromToActiveCriteria(example, searchValue, (Criteria) criteria, searchValues);
 203  0
                         } else if (KNSPropertyConstants.CURRENT.equals(propertyName)) {
 204  0
                                 addInactivateableFromToCurrentCriteria(example, searchValue, (Criteria) criteria, searchValues);
 205  0
                         } else if (!KNSPropertyConstants.ACTIVE_AS_OF_DATE.equals(propertyName)) {
 206  0
                                 addCriteria(propertyName, searchValue, propertyType, caseInsensitive,
 207  
                                                 treatWildcardsAndOperatorsAsLiteral, (Criteria) criteria);
 208  
                         }
 209  
                 } else {
 210  0
                         addCriteria(propertyName, searchValue, propertyType, caseInsensitive, treatWildcardsAndOperatorsAsLiteral,
 211  
                                         (Criteria) criteria);
 212  
                 }
 213  
         
 214  0
         return true;
 215  
     }
 216  
 
 217  
     /**
 218  
      * Find count of records meeting criteria based on the object and map.
 219  
      */
 220  
     public Long findCountByMap(Object example, Map formProps) {
 221  0
         Criteria criteria = new Criteria();
 222  
         // iterate through the parameter map for key values search criteria
 223  0
         Iterator propsIter = formProps.keySet().iterator();
 224  0
         while (propsIter.hasNext()) {
 225  0
             String propertyName = (String) propsIter.next();
 226  0
             String searchValue = (String) formProps.get(propertyName);
 227  
 
 228  
             // if searchValue is empty and the key is not a valid property ignore
 229  0
             if (StringUtils.isBlank(searchValue) || !(PropertyUtils.isWriteable(example, propertyName))) {
 230  0
                 continue;
 231  
             }
 232  
 
 233  
             // get property type which is used to determine type of criteria
 234  0
             Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
 235  0
             if (propertyType == null) {
 236  0
                 continue;
 237  
             }
 238  0
                 Boolean caseInsensitive = Boolean.TRUE;
 239  0
                 if ( KNSServiceLocatorWeb.getDataDictionaryService().isAttributeDefined( example.getClass(), propertyName )) {
 240  0
                         caseInsensitive = !KNSServiceLocatorWeb.getDataDictionaryService().getAttributeForceUppercase( example.getClass(), propertyName );
 241  
                 }
 242  0
                 if ( caseInsensitive == null ) { caseInsensitive = Boolean.TRUE; }
 243  
 
 244  0
                 boolean treatWildcardsAndOperatorsAsLiteral = KNSServiceLocatorWeb
 245  
                                         .getBusinessObjectDictionaryService().isLookupFieldTreatWildcardsAndOperatorsAsLiteral(example.getClass(), propertyName);
 246  
                 
 247  
             // build criteria
 248  0
             addCriteria(propertyName, searchValue, propertyType, caseInsensitive, treatWildcardsAndOperatorsAsLiteral, criteria);
 249  0
         }
 250  
 
 251  
         // execute query and return result list
 252  0
         Query query = QueryFactory.newQuery(example.getClass(), criteria);
 253  
 
 254  0
         return new Long(getPersistenceBrokerTemplate().getCount(query));
 255  
     }
 256  
 
 257  
     /**
 258  
      * @see org.kuali.rice.kns.dao.LookupDao#findObjectByMap(java.lang.Object, java.util.Map)
 259  
      */
 260  
     public Object findObjectByMap(Object example, Map formProps) {
 261  0
             if ( persistenceStructureService.isPersistable(example.getClass())) {
 262  0
                     Criteria criteria = new Criteria();
 263  
         
 264  
                     // iterate through the parameter map for key values search criteria
 265  0
                     Iterator propsIter = formProps.keySet().iterator();
 266  0
                     while (propsIter.hasNext()) {
 267  0
                             String propertyName = (String) propsIter.next();
 268  0
                             String searchValue = "";
 269  0
                             if (formProps.get(propertyName) != null) {
 270  0
                                     searchValue = (formProps.get(propertyName)).toString();
 271  
                             }
 272  
         
 273  0
                             if (StringUtils.isNotBlank(searchValue) & PropertyUtils.isWriteable(example, propertyName)) {
 274  0
                                     Class propertyType = ObjectUtils.getPropertyType(example, propertyName, persistenceStructureService);
 275  0
                                     if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
 276  0
                                             criteria.addEqualTo(propertyName, cleanNumeric(searchValue));
 277  0
                                     } else if (TypeUtils.isTemporalClass(propertyType)) {
 278  0
                                             criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(searchValue) ) );
 279  
                                     } else {
 280  0
                                             criteria.addEqualTo(propertyName, searchValue);
 281  
                                     }
 282  
                             }
 283  0
                     }
 284  
         
 285  
                     // execute query and return result list
 286  0
                     Query query = QueryFactory.newQuery(example.getClass(), criteria);
 287  0
                     return getPersistenceBrokerTemplate().getObjectByQuery(query);
 288  
             }
 289  0
             return null;
 290  
     }
 291  
 
 292  
 
 293  
     /**
 294  
      * Adds to the criteria object based on the property type and any query characters given.
 295  
      */
 296  
     private void addCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
 297  0
         if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, KNSConstants.OR_LOGICAL_OPERATOR)) {
 298  0
             addOrCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
 299  0
             return;
 300  
         }
 301  
 
 302  0
         if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, KNSConstants.AND_LOGICAL_OPERATOR)) {
 303  0
             addAndCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
 304  0
             return;
 305  
         }
 306  
 
 307  0
         if (StringUtils.containsIgnoreCase(propertyValue, KNSConstants.NULL_OPERATOR)) {
 308  0
                 if (StringUtils.contains(propertyValue, KNSConstants.NOT_LOGICAL_OPERATOR)) {
 309  0
                         criteria.addColumnNotNull(propertyName);
 310  
                 }
 311  
                 else {
 312  0
                         criteria.addColumnIsNull(propertyName);
 313  
                 }
 314  
         }
 315  0
         else if (TypeUtils.isStringClass(propertyType)) {
 316  
                 // KULRICE-85 : made string searches case insensitive - used new DBPlatform function to force strings to upper case
 317  0
                 if ( caseInsensitive ) {
 318  0
                         propertyName = getDbPlatform().getUpperCaseFunction() + "(" + propertyName + ")";
 319  0
                         propertyValue = propertyValue.toUpperCase();
 320  
                 }
 321  0
             if (!treatWildcardsAndOperatorsAsLiteral && StringUtils.contains(propertyValue, KNSConstants.NOT_LOGICAL_OPERATOR)) {
 322  0
                 addNotCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria);
 323  0
             } else if (
 324  
                             !treatWildcardsAndOperatorsAsLiteral && propertyValue != null && (
 325  
                                             StringUtils.contains(propertyValue, KNSConstants.BETWEEN_OPERATOR) 
 326  
                                             || propertyValue.startsWith(">")
 327  
                                             || propertyValue.startsWith("<") ) ) {
 328  0
                 addStringRangeCriteria(propertyName, propertyValue, criteria);
 329  
             } else {
 330  0
                     if (treatWildcardsAndOperatorsAsLiteral) {
 331  0
                             propertyValue = StringUtils.replace(propertyValue, "*", "\\*");
 332  
                     }
 333  0
                     criteria.addLike(propertyName, propertyValue);
 334  
             }
 335  0
         } else if (TypeUtils.isIntegralClass(propertyType) || TypeUtils.isDecimalClass(propertyType) ) {
 336  0
             addNumericRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
 337  0
         } else if (TypeUtils.isTemporalClass(propertyType)) {
 338  0
             addDateRangeCriteria(propertyName, propertyValue, treatWildcardsAndOperatorsAsLiteral, criteria);
 339  0
         } else if (TypeUtils.isBooleanClass(propertyType)) {
 340  0
             criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
 341  
         } else {
 342  0
             LOG.error("not adding criterion for: " + propertyName + "," + propertyType + "," + propertyValue);
 343  
         }
 344  0
     }
 345  
     
 346  
     /**
 347  
      * Translates criteria for active status to criteria on the active from and to fields
 348  
      * 
 349  
      * @param example - business object being queried on
 350  
      * @param activeSearchValue - value for the active search field, should convert to boolean
 351  
      * @param criteria - Criteria object being built
 352  
      * @param searchValues - Map containing all search keys and values
 353  
      */
 354  
     protected void addInactivateableFromToActiveCriteria(Object example, String activeSearchValue, Criteria criteria, Map searchValues) {
 355  0
                 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
 356  
                 
 357  0
             String activeBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(activeSearchValue);
 358  0
             if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
 359  
                     // (active from date <= date or active from date is null) and (date < active to date or active to date is null)
 360  0
                     Criteria criteriaBeginDate = new Criteria();
 361  0
                     criteriaBeginDate.addLessOrEqualThan(KNSPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
 362  
                     
 363  0
                     Criteria criteriaBeginDateNull = new Criteria();
 364  0
                     criteriaBeginDateNull.addIsNull(KNSPropertyConstants.ACTIVE_FROM_DATE);
 365  0
                     criteriaBeginDate.addOrCriteria(criteriaBeginDateNull);
 366  
                     
 367  0
                     criteria.addAndCriteria(criteriaBeginDate);
 368  
                     
 369  0
                     Criteria criteriaEndDate = new Criteria();
 370  0
                     criteriaEndDate.addGreaterThan(KNSPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
 371  
             
 372  0
                     Criteria criteriaEndDateNull = new Criteria();
 373  0
                     criteriaEndDateNull.addIsNull(KNSPropertyConstants.ACTIVE_TO_DATE);
 374  0
                     criteriaEndDate.addOrCriteria(criteriaEndDateNull);
 375  
                     
 376  0
                     criteria.addAndCriteria(criteriaEndDate);
 377  0
             }
 378  0
             else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(activeBooleanStr)) {
 379  
                     // (date < active from date) or (active from date is null) or (date >= active to date) 
 380  0
                     Criteria criteriaNonActive = new Criteria();
 381  0
                     criteriaNonActive.addGreaterThan(KNSPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
 382  
                     
 383  0
                     Criteria criteriaEndDate = new Criteria();
 384  0
                     criteriaEndDate.addLessOrEqualThan(KNSPropertyConstants.ACTIVE_TO_DATE, activeTimestamp);
 385  0
                     criteriaNonActive.addOrCriteria(criteriaEndDate);
 386  
                     
 387  0
                     criteria.addAndCriteria(criteriaNonActive);
 388  
             }
 389  0
     }
 390  
     
 391  
     /**
 392  
      * Translates criteria for current status to criteria on the active from field
 393  
      * 
 394  
      * @param example - business object being queried on
 395  
      * @param currentSearchValue - value for the current search field, should convert to boolean
 396  
      * @param criteria - Criteria object being built
 397  
      */
 398  
         protected void addInactivateableFromToCurrentCriteria(Object example, String currentSearchValue, Criteria criteria, Map searchValues) {
 399  0
                 Criteria maxBeginDateCriteria = new Criteria();
 400  
                 
 401  0
                 Timestamp activeTimestamp = LookupUtils.getActiveDateTimestampForCriteria(searchValues);
 402  
                 
 403  0
                 maxBeginDateCriteria.addLessOrEqualThan(KNSPropertyConstants.ACTIVE_FROM_DATE, activeTimestamp);
 404  
 
 405  0
                 List<String> groupByFieldList = businessObjectDictionaryService.getGroupByAttributesForEffectiveDating(example
 406  
                                 .getClass());
 407  0
                 if (groupByFieldList == null) {
 408  0
                         return;
 409  
                 }
 410  
 
 411  
                 // join back to main query with the group by fields
 412  0
                 String[] groupBy = new String[groupByFieldList.size()];
 413  0
                 for (int i = 0; i < groupByFieldList.size(); i++) {
 414  0
                         String groupByField = groupByFieldList.get(i);
 415  0
                         groupBy[i] = groupByField;
 416  
 
 417  0
                         maxBeginDateCriteria.addEqualToField(groupByField, Criteria.PARENT_QUERY_PREFIX + groupByField);
 418  
                 }
 419  
 
 420  0
                 String[] columns = new String[1];
 421  0
                 columns[0] = "max(" + KNSPropertyConstants.ACTIVE_FROM_DATE + ")";
 422  
 
 423  0
                 QueryByCriteria query = QueryFactory.newReportQuery(example.getClass(), columns, maxBeginDateCriteria, true);
 424  0
                 query.addGroupBy(groupBy);
 425  
 
 426  0
                 String currentBooleanStr = (String) (new OjbCharBooleanConversion()).javaToSql(currentSearchValue);
 427  0
                 if (OjbCharBooleanConversion.DATABASE_BOOLEAN_TRUE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
 428  0
                         criteria.addIn(KNSPropertyConstants.ACTIVE_FROM_DATE, query);
 429  0
                 } else if (OjbCharBooleanConversion.DATABASE_BOOLEAN_FALSE_STRING_REPRESENTATION.equals(currentBooleanStr)) {
 430  0
                         criteria.addNotIn(KNSPropertyConstants.ACTIVE_FROM_DATE, query);
 431  
                 }
 432  0
         }
 433  
 
 434  
     /**
 435  
      * @param propertyName
 436  
      * @param propertyValue
 437  
      * @param propertyType
 438  
      * @param criteria
 439  
      */
 440  
     private void addOrCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
 441  0
         addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, KNSConstants.OR_LOGICAL_OPERATOR);
 442  0
     }
 443  
        
 444  
     /**
 445  
      * @param propertyName
 446  
      * @param propertyValue
 447  
      * @param propertyType
 448  
      * @param criteria
 449  
      */
 450  
     private void addAndCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
 451  0
         addLogicalOperatorCriteria(propertyName, propertyValue, propertyType, caseInsensitive, criteria, KNSConstants.AND_LOGICAL_OPERATOR);
 452  0
     }
 453  
 
 454  
     private void addNotCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria) {
 455  
 
 456  0
         String[] splitPropVal = StringUtils.split(propertyValue, KNSConstants.NOT_LOGICAL_OPERATOR);
 457  
 
 458  0
         int strLength = splitPropVal.length;
 459  
         // if more than one NOT operator assume an implicit and (i.e. !a!b = !a&!b)
 460  0
         if (strLength > 1) {
 461  0
             String expandedNot = "!" + StringUtils.join(splitPropVal, KNSConstants.AND_LOGICAL_OPERATOR + KNSConstants.NOT_LOGICAL_OPERATOR);
 462  
             // we know that since this method was called, treatWildcardsAndOperatorsAsLiteral must be false
 463  0
             addCriteria(propertyName, expandedNot, propertyType, caseInsensitive, false, criteria);
 464  0
         }
 465  
         else {
 466  
             // only one so add a not like
 467  0
             criteria.addNotLike(propertyName, splitPropVal[0]);
 468  
         }
 469  0
     }
 470  
 
 471  
     /**
 472  
      * Builds a sub criteria object joined with an 'AND' or 'OR' (depending on splitValue) using the split values of propertyValue. Then joins back the
 473  
      * sub criteria to the main criteria using an 'AND'.
 474  
      */
 475  
     private void addLogicalOperatorCriteria(String propertyName, String propertyValue, Class propertyType, boolean caseInsensitive, Criteria criteria, String splitValue) {
 476  0
         String[] splitPropVal = StringUtils.split(propertyValue, splitValue);
 477  
 
 478  0
         Criteria subCriteria = new Criteria();
 479  0
         for (int i = 0; i < splitPropVal.length; i++) {
 480  0
                 Criteria predicate = new Criteria();
 481  
 
 482  0
             addCriteria(propertyName, splitPropVal[i], propertyType, caseInsensitive, false, predicate);
 483  0
             if (splitValue == KNSConstants.OR_LOGICAL_OPERATOR) {
 484  0
                     subCriteria.addOrCriteria(predicate);
 485  
             }
 486  0
             if (splitValue == KNSConstants.AND_LOGICAL_OPERATOR) {
 487  0
                     subCriteria.addAndCriteria(predicate);
 488  
             }
 489  
         }
 490  
 
 491  0
         criteria.addAndCriteria(subCriteria);
 492  0
     }
 493  
     
 494  
     private java.sql.Date parseDate(String dateString) {
 495  0
                 dateString = dateString.trim();
 496  
                 try {
 497  0
                         return dateTimeService.convertToSqlDate(dateString);
 498  0
                 } catch (ParseException ex) {
 499  0
                         return null;
 500  
                 }
 501  
         }
 502  
 
 503  
     /**
 504  
          * Adds to the criteria object based on query characters given
 505  
          */
 506  
     private void addDateRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
 507  
 
 508  0
         if (StringUtils.contains(propertyValue, KNSConstants.BETWEEN_OPERATOR)) {
 509  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 510  0
                         throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
 511  0
             String[] rangeValues = StringUtils.split(propertyValue, KNSConstants.BETWEEN_OPERATOR);
 512  0
             criteria.addBetween(propertyName, parseDate( ObjectUtils.clean(rangeValues[0] ) ), parseDate( ObjectUtils.clean(rangeValues[1] ) ) );
 513  0
         } else if (propertyValue.startsWith(">=")) {
 514  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 515  0
                         throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
 516  0
             criteria.addGreaterOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
 517  0
         } else if (propertyValue.startsWith("<=")) {
 518  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 519  0
                         throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
 520  0
             criteria.addLessOrEqualThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
 521  0
         } else if (propertyValue.startsWith(">")) {
 522  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 523  0
                         throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
 524  0
             criteria.addGreaterThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
 525  0
         } else if (propertyValue.startsWith("<")) {
 526  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 527  0
                         throw new RuntimeException("Wildcards and operators are not allowed on this date field: " + propertyName);
 528  0
             criteria.addLessThan(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
 529  
         } else {
 530  0
             criteria.addEqualTo(propertyName, parseDate( ObjectUtils.clean(propertyValue) ) );
 531  
         }
 532  0
     }
 533  
 
 534  
     private BigDecimal cleanNumeric( String value ) {
 535  0
         String cleanedValue = value.replaceAll( "[^-0-9.]", "" );
 536  
         // ensure only one "minus" at the beginning, if any
 537  0
         if ( cleanedValue.lastIndexOf( '-' ) > 0 ) {
 538  0
             if ( cleanedValue.charAt( 0 ) == '-' ) {
 539  0
                 cleanedValue = "-" + cleanedValue.replaceAll( "-", "" );
 540  
             } else {
 541  0
                 cleanedValue = cleanedValue.replaceAll( "-", "" );
 542  
             }
 543  
         }
 544  
         // ensure only one decimal in the string
 545  0
         int decimalLoc = cleanedValue.lastIndexOf( '.' );
 546  0
         if ( cleanedValue.indexOf( '.' ) != decimalLoc ) {
 547  0
             cleanedValue = cleanedValue.substring( 0, decimalLoc ).replaceAll( "\\.", "" ) + cleanedValue.substring( decimalLoc );
 548  
         }
 549  
         try {
 550  0
             return new BigDecimal( cleanedValue );
 551  0
         } catch ( NumberFormatException ex ) {
 552  0
             GlobalVariables.getMessageMap().putError(KNSConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_CUSTOM, new String[] { "Invalid Numeric Input: " + value });
 553  0
             return null;
 554  
         }
 555  
     }
 556  
 
 557  
     /**
 558  
      * Adds to the criteria object based on query characters given
 559  
      */
 560  
     private void addNumericRangeCriteria(String propertyName, String propertyValue, boolean treatWildcardsAndOperatorsAsLiteral, Criteria criteria) {
 561  
 
 562  0
         if (StringUtils.contains(propertyValue, KNSConstants.BETWEEN_OPERATOR)) {
 563  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 564  0
                         throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
 565  0
             String[] rangeValues = StringUtils.split(propertyValue, KNSConstants.BETWEEN_OPERATOR);
 566  0
             criteria.addBetween(propertyName, cleanNumeric( rangeValues[0] ), cleanNumeric( rangeValues[1] ));
 567  0
         } else if (propertyValue.startsWith(">=")) {
 568  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 569  0
                         throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
 570  0
             criteria.addGreaterOrEqualThan(propertyName, cleanNumeric(propertyValue));
 571  0
         } else if (propertyValue.startsWith("<=")) {
 572  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 573  0
                         throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
 574  0
             criteria.addLessOrEqualThan(propertyName, cleanNumeric(propertyValue));
 575  0
         } else if (propertyValue.startsWith(">")) {
 576  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 577  0
                         throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
 578  0
             criteria.addGreaterThan(propertyName, cleanNumeric( propertyValue ) );
 579  0
         } else if (propertyValue.startsWith("<")) {
 580  0
                 if (treatWildcardsAndOperatorsAsLiteral)
 581  0
                         throw new RuntimeException("Cannot use wildcards and operators on numeric field " + propertyName);
 582  0
             criteria.addLessThan(propertyName, cleanNumeric(propertyValue));
 583  
         } else {
 584  0
             criteria.addEqualTo(propertyName, cleanNumeric(propertyValue));
 585  
         }
 586  0
     }
 587  
 
 588  
     /**
 589  
      * Adds to the criteria object based on query characters given
 590  
      */
 591  
     private void addStringRangeCriteria(String propertyName, String propertyValue, Criteria criteria) {
 592  
 
 593  0
         if (StringUtils.contains(propertyValue, KNSConstants.BETWEEN_OPERATOR)) {
 594  0
             String[] rangeValues = StringUtils.split(propertyValue, KNSConstants.BETWEEN_OPERATOR);
 595  0
             criteria.addBetween(propertyName, rangeValues[0], rangeValues[1]);
 596  0
         } else if (propertyValue.startsWith(">=")) {
 597  0
             criteria.addGreaterOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
 598  0
         } else if (propertyValue.startsWith("<=")) {
 599  0
             criteria.addLessOrEqualThan(propertyName, ObjectUtils.clean(propertyValue));
 600  0
         } else if (propertyValue.startsWith(">")) {
 601  0
             criteria.addGreaterThan(propertyName, ObjectUtils.clean(propertyValue));
 602  0
         } else if (propertyValue.startsWith("<")) {
 603  0
             criteria.addLessThan(propertyName, ObjectUtils.clean(propertyValue));
 604  
         } else {
 605  0
                 criteria.addEqualTo(propertyName, ObjectUtils.clean(propertyValue));
 606  
         }
 607  0
     }
 608  
 
 609  
         public void setDateTimeService(DateTimeService dateTimeService) {
 610  0
                 this.dateTimeService = dateTimeService;
 611  0
         }
 612  
 
 613  
         public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
 614  0
                 this.businessObjectDictionaryService = businessObjectDictionaryService;
 615  0
         }
 616  
         
 617  
     public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
 618  0
         this.persistenceStructureService = persistenceStructureService;
 619  0
     }
 620  
 
 621  
 }