|  1 |     | 
     | 
  |  2 |     | 
     | 
  |  3 |     | 
     | 
  |  4 |     | 
     | 
  |  5 |     | 
     | 
  |  6 |     | 
     | 
  |  7 |     | 
     | 
  |  8 |     | 
     | 
  |  9 |     | 
     | 
  |  10 |     | 
     | 
  |  11 |     | 
     | 
  |  12 |     | 
     | 
  |  13 |     | 
     | 
  |  14 |     | 
     | 
  |  15 |     | 
     | 
  |  16 |     | 
   package org.kuali.rice.kew.docsearch;  | 
  |  17 |     | 
     | 
  |  18 |     | 
     | 
  |  19 |     | 
   import org.apache.commons.collections.CollectionUtils;  | 
  |  20 |     | 
   import org.apache.commons.lang.StringUtils;  | 
  |  21 |     | 
   import org.kuali.rice.core.api.exception.RiceRuntimeException;  | 
  |  22 |     | 
   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;  | 
  |  23 |     | 
   import org.kuali.rice.core.framework.persistence.jdbc.sql.Criteria;  | 
  |  24 |     | 
   import org.kuali.rice.core.framework.persistence.jdbc.sql.SQLUtils;  | 
  |  25 |     | 
   import org.kuali.rice.core.framework.persistence.jdbc.sql.SqlBuilder;  | 
  |  26 |     | 
   import org.kuali.rice.core.framework.persistence.platform.DatabasePlatform;  | 
  |  27 |     | 
   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;  | 
  |  28 |     | 
   import org.kuali.rice.core.util.RiceConstants;  | 
  |  29 |     | 
   import org.kuali.rice.core.util.RiceKeyConstants;  | 
  |  30 |     | 
   import org.kuali.rice.core.util.type.TypeUtils;  | 
  |  31 |     | 
   import org.kuali.rice.kew.doctype.SecuritySession;  | 
  |  32 |     | 
   import org.kuali.rice.kew.doctype.bo.DocumentType;  | 
  |  33 |     | 
   import org.kuali.rice.kew.doctype.service.DocumentTypeService;  | 
  |  34 |     | 
   import org.kuali.rice.kew.engine.node.RouteNode;  | 
  |  35 |     | 
   import org.kuali.rice.kew.exception.WorkflowRuntimeException;  | 
  |  36 |     | 
   import org.kuali.rice.kew.exception.WorkflowServiceError;  | 
  |  37 |     | 
   import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;  | 
  |  38 |     | 
   import org.kuali.rice.kew.rule.WorkflowAttributeValidationError;  | 
  |  39 |     | 
   import org.kuali.rice.kew.service.KEWServiceLocator;  | 
  |  40 |     | 
   import org.kuali.rice.kew.util.KEWConstants;  | 
  |  41 |     | 
   import org.kuali.rice.kew.util.PerformanceLogger;  | 
  |  42 |     | 
   import org.kuali.rice.kew.web.KeyValueSort;  | 
  |  43 |     | 
   import org.kuali.rice.kim.bo.Group;  | 
  |  44 |     | 
   import org.kuali.rice.kim.bo.Person;  | 
  |  45 |     | 
   import org.kuali.rice.kim.bo.entity.dto.KimEntityNamePrincipalNameInfo;  | 
  |  46 |     | 
   import org.kuali.rice.kim.service.KIMServiceLocator;  | 
  |  47 |     | 
   import org.kuali.rice.kns.UserSession;  | 
  |  48 |     | 
   import org.kuali.rice.kns.service.KNSServiceLocator;  | 
  |  49 |     | 
   import org.kuali.rice.kns.util.GlobalVariables;  | 
  |  50 |     | 
   import org.kuali.rice.kns.util.KNSConstants;  | 
  |  51 |     | 
   import org.kuali.rice.kns.util.MessageMap;  | 
  |  52 |     | 
   import org.kuali.rice.kns.util.ObjectUtils;  | 
  |  53 |     | 
     | 
  |  54 |     | 
   import java.math.BigDecimal;  | 
  |  55 |     | 
   import java.sql.ResultSet;  | 
  |  56 |     | 
   import java.sql.SQLException;  | 
  |  57 |     | 
   import java.sql.Statement;  | 
  |  58 |     | 
   import java.sql.Timestamp;  | 
  |  59 |     | 
   import java.text.SimpleDateFormat;  | 
  |  60 |     | 
   import java.util.ArrayList;  | 
  |  61 |     | 
   import java.util.Arrays;  | 
  |  62 |     | 
   import java.util.Calendar;  | 
  |  63 |     | 
   import java.util.Collection;  | 
  |  64 |     | 
   import java.util.HashMap;  | 
  |  65 |     | 
   import java.util.HashSet;  | 
  |  66 |     | 
   import java.util.Iterator;  | 
  |  67 |     | 
   import java.util.List;  | 
  |  68 |     | 
   import java.util.Map;  | 
  |  69 |     | 
   import java.util.Set;  | 
  |  70 |     | 
   import java.util.TreeSet;  | 
  |  71 |     | 
     | 
  |  72 |     | 
     | 
  |  73 |     | 
     | 
  |  74 |     | 
     | 
  |  75 |     | 
     | 
  |  76 |     | 
     | 
  |  77 |     | 
   public class StandardDocumentSearchGenerator implements DocumentSearchGenerator { | 
  |  78 |    0 |        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(StandardDocumentSearchGenerator.class);  | 
  |  79 |     | 
     | 
  |  80 |     | 
       private static final String ROUTE_NODE_TABLE = "KREW_RTE_NODE_T";  | 
  |  81 |     | 
       private static final String ROUTE_NODE_INST_TABLE = "KREW_RTE_NODE_INSTN_T";  | 
  |  82 |     | 
       private static final String DATABASE_WILDCARD_CHARACTER_STRING = "%";  | 
  |  83 |    0 |        private static final char DATABASE_WILDCARD_CHARACTER = DATABASE_WILDCARD_CHARACTER_STRING.toCharArray()[0];  | 
  |  84 |     | 
     | 
  |  85 |     | 
       private static List<SearchableAttribute> searchableAttributes;  | 
  |  86 |     | 
       private static DocSearchCriteriaDTO criteria;  | 
  |  87 |     | 
       private static String searchingUser;  | 
  |  88 |     | 
     | 
  |  89 |    0 |        private boolean isProcessResultSet = true;  | 
  |  90 |     | 
     | 
  |  91 |     | 
       private DatabasePlatform dbPlatform;  | 
  |  92 |     | 
       private MessageMap messageMap;  | 
  |  93 |     | 
     | 
  |  94 |    0 |        private SqlBuilder sqlBuilder = null;  | 
  |  95 |     | 
     | 
  |  96 |     | 
       public StandardDocumentSearchGenerator() { | 
  |  97 |    0 |            super();  | 
  |  98 |    0 |            searchableAttributes = new ArrayList<SearchableAttribute>();  | 
  |  99 |    0 |        }  | 
  |  100 |     | 
     | 
  |  101 |     | 
         | 
  |  102 |     | 
     | 
  |  103 |     | 
     | 
  |  104 |     | 
       public StandardDocumentSearchGenerator(List<SearchableAttribute> searchableAttributes) { | 
  |  105 |    0 |            this();  | 
  |  106 |    0 |            StandardDocumentSearchGenerator.searchableAttributes = searchableAttributes;  | 
  |  107 |    0 |        }  | 
  |  108 |     | 
     | 
  |  109 |     | 
       public DocSearchCriteriaDTO getCriteria() { | 
  |  110 |    0 |            return criteria;  | 
  |  111 |     | 
       }  | 
  |  112 |     | 
     | 
  |  113 |     | 
       public void setCriteria(DocSearchCriteriaDTO criteria) { | 
  |  114 |    0 |            StandardDocumentSearchGenerator.criteria = criteria;  | 
  |  115 |    0 |        }  | 
  |  116 |     | 
     | 
  |  117 |     | 
       public List<SearchableAttribute> getSearchableAttributes() { | 
  |  118 |    0 |            return searchableAttributes;  | 
  |  119 |     | 
       }  | 
  |  120 |     | 
     | 
  |  121 |     | 
       public void setSearchableAttributes(List<SearchableAttribute> searchableAttributes) { | 
  |  122 |    0 |            this.searchableAttributes = searchableAttributes;  | 
  |  123 |    0 |        }  | 
  |  124 |     | 
     | 
  |  125 |     | 
       public String getSearchingUser() { | 
  |  126 |    0 |            return searchingUser;  | 
  |  127 |     | 
       }  | 
  |  128 |     | 
     | 
  |  129 |     | 
       public void setSearchingUser(String searchingUser) { | 
  |  130 |    0 |            StandardDocumentSearchGenerator.searchingUser = searchingUser;  | 
  |  131 |    0 |        }  | 
  |  132 |     | 
     | 
  |  133 |     | 
       public DocSearchCriteriaDTO clearSearch(DocSearchCriteriaDTO searchCriteria) { | 
  |  134 |    0 |            return new DocSearchCriteriaDTO();  | 
  |  135 |     | 
       }  | 
  |  136 |     | 
     | 
  |  137 |     | 
       public List<WorkflowServiceError> performPreSearchConditions(String principalId, DocSearchCriteriaDTO searchCriteria) { | 
  |  138 |    0 |            setCriteria(searchCriteria);  | 
  |  139 |    0 |            return new ArrayList<WorkflowServiceError>();  | 
  |  140 |     | 
       }  | 
  |  141 |     | 
     | 
  |  142 |     | 
       public SearchAttributeCriteriaComponent getSearchableAttributeByFieldName(String name) { | 
  |  143 |    0 |            if (StringUtils.isBlank(name)) { | 
  |  144 |    0 |                throw new IllegalArgumentException("Attempted to find Searchable Attribute with blank Field name '" + name + "'"); | 
  |  145 |     | 
           }  | 
  |  146 |    0 |            for (SearchAttributeCriteriaComponent critComponent : getCriteria().getSearchableAttributes())  | 
  |  147 |     | 
           { | 
  |  148 |     | 
     | 
  |  149 |    0 |                if (name.equals(critComponent.getFormKey()))  | 
  |  150 |     | 
               { | 
  |  151 |    0 |                    return critComponent;  | 
  |  152 |     | 
               }  | 
  |  153 |     | 
           }  | 
  |  154 |    0 |            return null;  | 
  |  155 |     | 
       }  | 
  |  156 |     | 
     | 
  |  157 |     | 
       public void addErrorMessageToList(List<WorkflowServiceError> errors, String message) { | 
  |  158 |    0 |            errors.add(new WorkflowServiceErrorImpl(message,"general.message",message));  | 
  |  159 |    0 |        }  | 
  |  160 |     | 
     | 
  |  161 |     | 
         | 
  |  162 |     | 
     | 
  |  163 |     | 
     | 
  |  164 |     | 
       public String generateSearchSql(DocSearchCriteriaDTO searchCriteria) { | 
  |  165 |    0 |            setCriteria(searchCriteria);  | 
  |  166 |    0 |            return getDocSearchSQL();  | 
  |  167 |     | 
       }  | 
  |  168 |     | 
     | 
  |  169 |     | 
       public DocumentType getValidDocumentType(String documentTypeFullName) { | 
  |  170 |    0 |            if (!org.apache.commons.lang.StringUtils.isEmpty(documentTypeFullName)) { | 
  |  171 |    0 |                DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeFullName);  | 
  |  172 |    0 |                if (documentType == null) { | 
  |  173 |    0 |                    throw new RuntimeException("No Valid Document Type Found for document type name '" + documentTypeFullName + "'"); | 
  |  174 |     | 
               }  | 
  |  175 |    0 |                return documentType;  | 
  |  176 |     | 
           }  | 
  |  177 |    0 |            return null;  | 
  |  178 |     | 
       }  | 
  |  179 |     | 
     | 
  |  180 |     | 
         | 
  |  181 |     | 
     | 
  |  182 |     | 
     | 
  |  183 |     | 
       public List<WorkflowServiceError> validateSearchableAttributes(DocSearchCriteriaDTO searchCriteria) { | 
  |  184 |    0 |            setCriteria(searchCriteria);  | 
  |  185 |    0 |            List<WorkflowServiceError> errors = new ArrayList<WorkflowServiceError>();  | 
  |  186 |    0 |            List<SearchAttributeCriteriaComponent> searchableAttributes = criteria.getSearchableAttributes();  | 
  |  187 |    0 |            if (searchableAttributes != null && !searchableAttributes.isEmpty()) { | 
  |  188 |    0 |                Map<String, Object> paramMap = new HashMap<String, Object>();  | 
  |  189 |    0 |                for (SearchAttributeCriteriaComponent component : searchableAttributes) { | 
  |  190 |    0 |                    if (!CollectionUtils.isEmpty(component.getValues())) { | 
  |  191 |    0 |                        paramMap.put(component.getFormKey(),component.getValues());  | 
  |  192 |     | 
                   } else { | 
  |  193 |    0 |                        paramMap.put(component.getFormKey(),component.getValue());  | 
  |  194 |     | 
                   }  | 
  |  195 |     | 
               }  | 
  |  196 |    0 |                DocumentType documentType = getValidDocumentType(criteria.getDocTypeFullName());  | 
  |  197 |     | 
               try { | 
  |  198 |    0 |                    for (SearchableAttribute searchableAttribute : documentType.getSearchableAttributes()) { | 
  |  199 |    0 |                        List<WorkflowAttributeValidationError> searchableErrors = validateSearchableAttribute(  | 
  |  200 |     | 
                               searchableAttribute, paramMap, DocSearchUtils.getDocumentSearchContext("", documentType.getName(), "")); | 
  |  201 |    0 |                        if(!CollectionUtils.isEmpty(searchableErrors)){ | 
  |  202 |    0 |                            for (WorkflowAttributeValidationError error : searchableErrors) { | 
  |  203 |    0 |                                        if (error.getMessageMap() != null && error.getMessageMap().hasErrors()) { | 
  |  204 |     | 
                                                 | 
  |  205 |    0 |                                                errors.add(new WorkflowServiceErrorImpl(error.getKey(), "routetemplate.xmlattribute.error",   | 
  |  206 |     | 
                                                               error.getMessage(), null, error.getMessageMap()));  | 
  |  207 |     | 
                                       } else { | 
  |  208 |    0 |                                errors.add(new WorkflowServiceErrorImpl(error.getKey(), "routetemplate.xmlattribute.error", error.getMessage()));  | 
  |  209 |     | 
                           }  | 
  |  210 |     | 
                       }  | 
  |  211 |     | 
                   }  | 
  |  212 |    0 |                        }  | 
  |  213 |    0 |                } catch (Exception e) { | 
  |  214 |    0 |                    LOG.error("error finding searchable attribute in when validating document search criteria.", e); | 
  |  215 |    0 |                }  | 
  |  216 |     | 
           }  | 
  |  217 |    0 |            return errors;  | 
  |  218 |     | 
       }  | 
  |  219 |     | 
     | 
  |  220 |     | 
       public List<WorkflowAttributeValidationError> validateSearchableAttribute(  | 
  |  221 |     | 
               SearchableAttribute searchableAttribute, Map searchAttributesParameterMap, DocumentSearchContext documentSearchContext) { | 
  |  222 |    0 |            return searchableAttribute.validateUserSearchInputs(searchAttributesParameterMap, documentSearchContext);  | 
  |  223 |     | 
       }  | 
  |  224 |     | 
     | 
  |  225 |     | 
       private Class getSearchableAttributeClass(SearchableAttributeValue sav){ | 
  |  226 |    0 |            if(sav instanceof SearchableAttributeDateTimeValue){ | 
  |  227 |    0 |                return Timestamp.class;  | 
  |  228 |    0 |            }else if(sav instanceof SearchableAttributeFloatValue){ | 
  |  229 |    0 |                return Float.TYPE;  | 
  |  230 |    0 |            }else if(sav instanceof SearchableAttributeLongValue){ | 
  |  231 |    0 |                return Long.TYPE;  | 
  |  232 |    0 |            }else if(sav instanceof SearchableAttributeStringValue){ | 
  |  233 |    0 |                return String.class;  | 
  |  234 |     | 
           }else{ | 
  |  235 |    0 |                return null;  | 
  |  236 |     | 
           }  | 
  |  237 |     | 
       }  | 
  |  238 |     | 
     | 
  |  239 |     | 
         | 
  |  240 |     | 
     | 
  |  241 |     | 
     | 
  |  242 |     | 
     | 
  |  243 |     | 
     | 
  |  244 |     | 
       private static List<String> cleanUpperBounds(List<String> stringDates) { | 
  |  245 |    0 |            List<String> lRet = null;  | 
  |  246 |    0 |            if(stringDates != null && !stringDates.isEmpty()){ | 
  |  247 |    0 |                lRet = new ArrayList<String>();  | 
  |  248 |    0 |                for(String stringDate:stringDates){ | 
  |  249 |    0 |                    lRet.add(cleanUpperBound(stringDate));  | 
  |  250 |     | 
               }  | 
  |  251 |     | 
           }  | 
  |  252 |    0 |            return lRet;  | 
  |  253 |     | 
       }  | 
  |  254 |     | 
         | 
  |  255 |     | 
         | 
  |  256 |     | 
     | 
  |  257 |     | 
     | 
  |  258 |     | 
     | 
  |  259 |     | 
     | 
  |  260 |     | 
     | 
  |  261 |     | 
     | 
  |  262 |     | 
       private static String cleanUpperBound(String stringDate){ | 
  |  263 |     | 
           try{ | 
  |  264 |    0 |                java.sql.Timestamp dt = KNSServiceLocator.getDateTimeService().convertToSqlTimestamp(stringDate);  | 
  |  265 |    0 |                SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss"); | 
  |  266 |     | 
     | 
  |  267 |    0 |                if("00:00:00".equals(sdfTime.format(dt))){ | 
  |  268 |    0 |                    stringDate = stringDate + " 23:59:59";  | 
  |  269 |     | 
               }  | 
  |  270 |    0 |            } catch (Exception ex){ | 
  |  271 |    0 |                GlobalVariables.getMessageMap().putError(KNSConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_CUSTOM, new String[] { "Invalid Date Input: " + stringDate }); | 
  |  272 |    0 |            }  | 
  |  273 |    0 |            return stringDate;  | 
  |  274 |     | 
       }  | 
  |  275 |     | 
     | 
  |  276 |     | 
     | 
  |  277 |     | 
         | 
  |  278 |     | 
     | 
  |  279 |     | 
     | 
  |  280 |     | 
     | 
  |  281 |     | 
     | 
  |  282 |     | 
     | 
  |  283 |     | 
     | 
  |  284 |     | 
     | 
  |  285 |     | 
     | 
  |  286 |     | 
     | 
  |  287 |     | 
     | 
  |  288 |     | 
     | 
  |  289 |     | 
     | 
  |  290 |     | 
       private static String parseAndConvertDateToRange(String propertyValue) { | 
  |  291 |     | 
     | 
  |  292 |    0 |            String sRet = propertyValue;  | 
  |  293 |     | 
     | 
  |  294 |    0 |            if (StringUtils.contains(propertyValue, KNSConstants.BETWEEN_OPERATOR)) { | 
  |  295 |    0 |                String[] rangeValues = propertyValue.split("\\.\\.");  | 
  |  296 |    0 |                sRet = ObjectUtils.clean(rangeValues[0].trim())+ " .. " + cleanUpperBound(ObjectUtils.clean(rangeValues[1].trim()));  | 
  |  297 |    0 |            }  else if (propertyValue.startsWith("<=")) { | 
  |  298 |    0 |                sRet = "<=" + cleanUpperBound(ObjectUtils.clean(propertyValue));  | 
  |  299 |    0 |            }  else if (propertyValue.startsWith("<")) { | 
  |  300 |    0 |                sRet = "<" + cleanUpperBound(ObjectUtils.clean(propertyValue));  | 
  |  301 |     | 
           }  | 
  |  302 |     | 
     | 
  |  303 |    0 |            return sRet;  | 
  |  304 |     | 
       }  | 
  |  305 |     | 
     | 
  |  306 |     | 
     | 
  |  307 |     | 
     | 
  |  308 |     | 
         | 
  |  309 |     | 
     | 
  |  310 |     | 
     | 
  |  311 |     | 
     | 
  |  312 |     | 
     | 
  |  313 |     | 
     | 
  |  314 |     | 
     | 
  |  315 |     | 
     | 
  |  316 |     | 
     | 
  |  317 |     | 
     | 
  |  318 |     | 
       private void validateBounds(SearchAttributeCriteriaComponent lowerBound, SearchAttributeCriteriaComponent upperBound){ | 
  |  319 |     | 
     | 
  |  320 |    0 |            Class type = getSearchableAttributeClass(lowerBound.getSearchableAttributeValue());  | 
  |  321 |    0 |            Class upperType = getSearchableAttributeClass(upperBound.getSearchableAttributeValue());  | 
  |  322 |     | 
     | 
  |  323 |     | 
             | 
  |  324 |    0 |            if(type.getName().compareTo(upperType.getName()) != 0){ | 
  |  325 |    0 |                String err = "Type Mismatch. Must compare two like types";  | 
  |  326 |    0 |                LOG.error("validateBounds() " + err); | 
  |  327 |    0 |                throw new RuntimeException(err);  | 
  |  328 |     | 
           }  | 
  |  329 |     | 
     | 
  |  330 |    0 |            String errorMsg = "The search attribute range values are out of order. Lower bound must be <= Upper Bound. ["  | 
  |  331 |     | 
               + lowerBound.getValue() + ", " + upperBound.getValue() + "] for type " + type.getName();  | 
  |  332 |     | 
     | 
  |  333 |    0 |            if(TypeUtils.isIntegralClass(type) || TypeUtils.isDecimalClass(type)){ | 
  |  334 |     | 
                 | 
  |  335 |    0 |                BigDecimal lVal = SqlBuilder.stringToBigDecimal(lowerBound.getValue());  | 
  |  336 |    0 |                BigDecimal uVal = SqlBuilder.stringToBigDecimal(upperBound.getValue());  | 
  |  337 |     | 
     | 
  |  338 |    0 |                if(lVal.compareTo(uVal) > 0){ | 
  |  339 |    0 |                    LOG.error("validateBounds() " + errorMsg); | 
  |  340 |    0 |                    throw new RuntimeException(errorMsg);  | 
  |  341 |     | 
               }  | 
  |  342 |     | 
     | 
  |  343 |    0 |            }else if(TypeUtils.isTemporalClass(type)){ | 
  |  344 |    0 |                java.sql.Timestamp lVal = null;  | 
  |  345 |    0 |                java.sql.Timestamp uVal = null;  | 
  |  346 |     | 
               try{ | 
  |  347 |    0 |                    lVal = KNSServiceLocator.getDateTimeService().convertToSqlTimestamp(lowerBound.getValue());  | 
  |  348 |    0 |                    uVal = KNSServiceLocator.getDateTimeService().convertToSqlTimestamp(upperBound.getValue());  | 
  |  349 |    0 |                }catch(Exception ex){ | 
  |  350 |    0 |                    LOG.error("validateBounds() " + errorMsg); | 
  |  351 |    0 |                    throw new RuntimeException(errorMsg, ex);  | 
  |  352 |    0 |                }  | 
  |  353 |     | 
     | 
  |  354 |    0 |                if(lVal.compareTo(uVal) > 0){ | 
  |  355 |    0 |                    LOG.error("validateBounds() " + errorMsg); | 
  |  356 |    0 |                    throw new RuntimeException(errorMsg);  | 
  |  357 |     | 
               }  | 
  |  358 |     | 
     | 
  |  359 |    0 |            }else if(TypeUtils.isStringClass(type)){ | 
  |  360 |     | 
                 | 
  |  361 |     | 
                 | 
  |  362 |    0 |                if(lowerBound.isCaseSensitive() != upperBound.isCaseSensitive()){ | 
  |  363 |    0 |                    LOG.warn("validateBounds(): Cannot Validate because mismatch case sensitivity [" | 
  |  364 |     | 
                           + lowerBound.getValue() + ", " + upperBound.getValue() + "] for type " + type.getName());  | 
  |  365 |    0 |                }else if(lowerBound.isCaseSensitive()){ | 
  |  366 |    0 |                    if(lowerBound.getValue().compareTo(upperBound.getValue()) > 0){ | 
  |  367 |    0 |                        LOG.error("validateBounds() " + errorMsg); | 
  |  368 |    0 |                        throw new RuntimeException(errorMsg);  | 
  |  369 |     | 
                   }  | 
  |  370 |     | 
               }else{ | 
  |  371 |    0 |                    if(lowerBound.getValue().compareToIgnoreCase(upperBound.getValue()) > 0){ | 
  |  372 |    0 |                        LOG.error("validateBounds() " + errorMsg); | 
  |  373 |    0 |                        throw new RuntimeException(errorMsg);  | 
  |  374 |     | 
                   }  | 
  |  375 |     | 
               }  | 
  |  376 |     | 
           }  | 
  |  377 |    0 |        }  | 
  |  378 |     | 
     | 
  |  379 |     | 
         | 
  |  380 |     | 
     | 
  |  381 |     | 
     | 
  |  382 |     | 
     | 
  |  383 |     | 
     | 
  |  384 |     | 
     | 
  |  385 |     | 
     | 
  |  386 |     | 
     | 
  |  387 |     | 
     | 
  |  388 |     | 
     | 
  |  389 |     | 
     | 
  |  390 |     | 
     | 
  |  391 |     | 
     | 
  |  392 |     | 
     | 
  |  393 |     | 
     | 
  |  394 |     | 
       private void combineAndFormatSearchableComponents(  | 
  |  395 |     | 
               List<SearchAttributeCriteriaComponent> searchableAttributes) { | 
  |  396 |     | 
     | 
  |  397 |    0 |            Map<String, List<SearchAttributeCriteriaComponent>> searchableAttributeRangeComponents = new HashMap<String, List<SearchAttributeCriteriaComponent>>();  | 
  |  398 |     | 
     | 
  |  399 |    0 |            for (SearchAttributeCriteriaComponent criteriaComponent : searchableAttributes)  | 
  |  400 |     | 
           { | 
  |  401 |    0 |                if (!criteriaComponent.isSearchable())  | 
  |  402 |     | 
               { | 
  |  403 |    0 |                    continue;  | 
  |  404 |     | 
               }  | 
  |  405 |     | 
     | 
  |  406 |    0 |                SearchableAttributeValue searchAttribute = criteriaComponent.getSearchableAttributeValue();  | 
  |  407 |    0 |                if (searchAttribute == null)  | 
  |  408 |     | 
               { | 
  |  409 |     | 
                     | 
  |  410 |    0 |                    String errorMsg = "The search attribute value associated with key '"  | 
  |  411 |     | 
                           + criteriaComponent.getSavedKey() + "' cannot be found";  | 
  |  412 |    0 |                    LOG.error("getSearchableAttributeSql() " + errorMsg); | 
  |  413 |    0 |                    throw new RuntimeException(errorMsg);  | 
  |  414 |     | 
               }  | 
  |  415 |     | 
     | 
  |  416 |    0 |                Class clazz = getSearchableAttributeClass(searchAttribute);  | 
  |  417 |     | 
     | 
  |  418 |    0 |                if (criteriaComponent.isRangeSearch())  | 
  |  419 |     | 
               { | 
  |  420 |     | 
     | 
  |  421 |    0 |                    if (searchableAttributeRangeComponents.containsKey(criteriaComponent.getSavedKey()))  | 
  |  422 |     | 
                   { | 
  |  423 |    0 |                        List<SearchAttributeCriteriaComponent> criteriaComponents = searchableAttributeRangeComponents.get(criteriaComponent.getSavedKey());  | 
  |  424 |    0 |                        List<SearchAttributeCriteriaComponent> newCriteriaComponents = new ArrayList<SearchAttributeCriteriaComponent>();  | 
  |  425 |    0 |                        newCriteriaComponents.addAll(criteriaComponents);  | 
  |  426 |    0 |                        newCriteriaComponents.add(criteriaComponent);  | 
  |  427 |    0 |                        searchableAttributeRangeComponents.put(criteriaComponent.getSavedKey(), newCriteriaComponents);  | 
  |  428 |    0 |                    } else  | 
  |  429 |     | 
                   { | 
  |  430 |    0 |                        searchableAttributeRangeComponents.put(criteriaComponent.getSavedKey(),  | 
  |  431 |     | 
                               Arrays.asList(criteriaComponent)  | 
  |  432 |     | 
                       );  | 
  |  433 |     | 
                   }  | 
  |  434 |     | 
                     | 
  |  435 |     | 
                     | 
  |  436 |    0 |                    if (TypeUtils.isTemporalClass(clazz) && criteriaComponent.isComponentUpperBoundValue())  | 
  |  437 |     | 
                   { | 
  |  438 |    0 |                        criteriaComponent.setValue(cleanUpperBound(criteriaComponent.getValue()));  | 
  |  439 |    0 |                        criteriaComponent.setValues(cleanUpperBounds(criteriaComponent.getValues()));  | 
  |  440 |     | 
                   }  | 
  |  441 |     | 
     | 
  |  442 |     | 
               } else  | 
  |  443 |     | 
               { | 
  |  444 |    0 |                    if (TypeUtils.isTemporalClass(clazz))  | 
  |  445 |     | 
                   { | 
  |  446 |    0 |                        criteriaComponent.setValue(criteriaComponent.getValue());  | 
  |  447 |     | 
                   }  | 
  |  448 |     | 
               }  | 
  |  449 |    0 |            }  | 
  |  450 |     | 
     | 
  |  451 |     | 
             | 
  |  452 |     | 
             | 
  |  453 |    0 |            for (String keyName : searchableAttributeRangeComponents.keySet()) { | 
  |  454 |    0 |                List<SearchAttributeCriteriaComponent> criteriaComponents = searchableAttributeRangeComponents  | 
  |  455 |     | 
                       .get(keyName);  | 
  |  456 |     | 
     | 
  |  457 |    0 |                SearchAttributeCriteriaComponent newComp = null;  | 
  |  458 |    0 |                SearchAttributeCriteriaComponent lowerBound = null;  | 
  |  459 |    0 |                SearchAttributeCriteriaComponent upperBound = null;  | 
  |  460 |     | 
     | 
  |  461 |    0 |                for (SearchAttributeCriteriaComponent component : criteriaComponents) { | 
  |  462 |    0 |                    if (component.isComponentLowerBoundValue()) { | 
  |  463 |    0 |                        lowerBound = component;  | 
  |  464 |    0 |                    } else if (component.isComponentUpperBoundValue()) { | 
  |  465 |    0 |                        upperBound = component;  | 
  |  466 |     | 
                   } else { | 
  |  467 |    0 |                        String errorMsg = "The search attribute value associated with key '"  | 
  |  468 |     | 
                               + component.getSavedKey()  | 
  |  469 |     | 
                               + "' is not upper or lower bound";  | 
  |  470 |    0 |                        LOG.error("getSearchableAttributeSql() " + errorMsg); | 
  |  471 |    0 |                        throw new RuntimeException(errorMsg);  | 
  |  472 |     | 
                   }  | 
  |  473 |     | 
               }  | 
  |  474 |     | 
     | 
  |  475 |     | 
                 | 
  |  476 |     | 
                 | 
  |  477 |    0 |                if (lowerBound != null && upperBound != null) {  | 
  |  478 |     | 
     | 
  |  479 |     | 
                     | 
  |  480 |    0 |                    validateBounds(lowerBound, upperBound);  | 
  |  481 |     | 
     | 
  |  482 |     | 
                     | 
  |  483 |     | 
                     | 
  |  484 |     | 
                     | 
  |  485 |     | 
     | 
  |  486 |    0 |                    lowerBound.setRangeSearch(false);  | 
  |  487 |    0 |                    upperBound.setRangeSearch(false);  | 
  |  488 |    0 |                    if (lowerBound.isSearchInclusive()) { | 
  |  489 |    0 |                        lowerBound.setValue(">=" + lowerBound.getValue()); | 
  |  490 |     | 
                   } else { | 
  |  491 |    0 |                        lowerBound.setValue(">" + lowerBound.getValue()); | 
  |  492 |     | 
                   }  | 
  |  493 |    0 |                    if (upperBound.isSearchInclusive()) { | 
  |  494 |    0 |                        upperBound.setValue("<=" + upperBound.getValue()); | 
  |  495 |     | 
                   } else { | 
  |  496 |    0 |                        upperBound.setValue("<" + upperBound.getValue()); | 
  |  497 |     | 
                   }  | 
  |  498 |     | 
     | 
  |  499 |    0 |                } else if (lowerBound != null) { | 
  |  500 |    0 |                    newComp = new SearchAttributeCriteriaComponent(lowerBound  | 
  |  501 |     | 
                           .getFormKey(), null, false);  | 
  |  502 |    0 |                    if (lowerBound.isSearchInclusive()) { | 
  |  503 |    0 |                        newComp.setValue(">=" + lowerBound.getValue()); | 
  |  504 |     | 
                   } else { | 
  |  505 |    0 |                        newComp.setValue(">" + lowerBound.getValue()); | 
  |  506 |     | 
                   }  | 
  |  507 |    0 |                    newComp.setSearchInclusive(lowerBound.isSearchInclusive());  | 
  |  508 |    0 |                    newComp.setCaseSensitive(lowerBound.isCaseSensitive());  | 
  |  509 |    0 |                    newComp.setAllowInlineRange(lowerBound.isAllowInlineRange());  | 
  |  510 |    0 |                    newComp.setCanHoldMultipleValues(lowerBound  | 
  |  511 |     | 
                           .isCanHoldMultipleValues());  | 
  |  512 |    0 |                    newComp.setLookupableFieldType(lowerBound  | 
  |  513 |     | 
                           .getLookupableFieldType());  | 
  |  514 |    0 |                    newComp.setSearchable(true);  | 
  |  515 |    0 |                    newComp.setSearchableAttributeValue(lowerBound  | 
  |  516 |     | 
                           .getSearchableAttributeValue());  | 
  |  517 |    0 |                    newComp.setSavedKey(lowerBound.getSavedKey());  | 
  |  518 |    0 |                    searchableAttributes.add(newComp);  | 
  |  519 |    0 |                } else if (upperBound != null) { | 
  |  520 |    0 |                    newComp = new SearchAttributeCriteriaComponent(upperBound  | 
  |  521 |     | 
                           .getFormKey(), null, false);  | 
  |  522 |    0 |                    if (upperBound.isSearchInclusive()) { | 
  |  523 |    0 |                        newComp.setValue("<=" + upperBound.getValue()); | 
  |  524 |     | 
                   } else { | 
  |  525 |    0 |                        newComp.setValue("<" + upperBound.getValue()); | 
  |  526 |     | 
                   }  | 
  |  527 |    0 |                    newComp.setSearchInclusive(upperBound.isSearchInclusive());  | 
  |  528 |    0 |                    newComp.setCaseSensitive(upperBound.isCaseSensitive());  | 
  |  529 |    0 |                    newComp.setAllowInlineRange(upperBound.isAllowInlineRange());  | 
  |  530 |    0 |                    newComp.setCanHoldMultipleValues(upperBound.isCanHoldMultipleValues());  | 
  |  531 |    0 |                    newComp.setLookupableFieldType(upperBound.getLookupableFieldType());  | 
  |  532 |    0 |                    newComp.setSearchable(true);  | 
  |  533 |    0 |                    newComp.setSearchableAttributeValue(upperBound.getSearchableAttributeValue());  | 
  |  534 |    0 |                    newComp.setSavedKey(upperBound.getSavedKey());  | 
  |  535 |    0 |                    searchableAttributes.add(newComp);  | 
  |  536 |     | 
               }  | 
  |  537 |     | 
     | 
  |  538 |    0 |            }  | 
  |  539 |     | 
     | 
  |  540 |     | 
             | 
  |  541 |     | 
             | 
  |  542 |    0 |            for (Iterator<SearchAttributeCriteriaComponent> iterator = searchableAttributes.iterator(); iterator  | 
  |  543 |    0 |                    .hasNext();) { | 
  |  544 |    0 |                SearchAttributeCriteriaComponent criteriaComponent = (SearchAttributeCriteriaComponent) iterator  | 
  |  545 |     | 
                       .next();  | 
  |  546 |    0 |                if (!criteriaComponent.isSearchable()) { | 
  |  547 |    0 |                    continue;  | 
  |  548 |     | 
               }  | 
  |  549 |     | 
     | 
  |  550 |    0 |                if (criteriaComponent.isRangeSearch()) { | 
  |  551 |    0 |                    iterator.remove();  | 
  |  552 |     | 
               }  | 
  |  553 |     | 
     | 
  |  554 |    0 |            }  | 
  |  555 |    0 |        }  | 
  |  556 |     | 
     | 
  |  557 |     | 
       public QueryComponent getSearchableAttributeSql(List<SearchAttributeCriteriaComponent> searchableAttributes, String whereClausePredicatePrefix) { | 
  |  558 |     | 
             | 
  |  559 |     | 
     | 
  |  560 |     | 
     | 
  |  561 |     | 
     | 
  |  562 |     | 
     | 
  |  563 |     | 
     | 
  |  564 |     | 
             | 
  |  565 |    0 |            combineAndFormatSearchableComponents(searchableAttributes);  | 
  |  566 |     | 
     | 
  |  567 |    0 |            StringBuffer fromSql = new StringBuffer();  | 
  |  568 |    0 |            StringBuffer whereSql = new StringBuffer();  | 
  |  569 |     | 
     | 
  |  570 |    0 |            int tableIndex = 1;  | 
  |  571 |    0 |            String tableAlias = "EXT" + tableIndex;  | 
  |  572 |     | 
     | 
  |  573 |    0 |            Map<String, List<SearchAttributeCriteriaComponent>> searchableAttributeRangeComponents = new HashMap<String,List<SearchAttributeCriteriaComponent>>();  | 
  |  574 |    0 |            Criteria finalCriteria = null;  | 
  |  575 |     | 
     | 
  |  576 |    0 |            for (Iterator<SearchAttributeCriteriaComponent> iterator = searchableAttributes.iterator(); iterator.hasNext(); tableIndex++) { | 
  |  577 |    0 |                SearchAttributeCriteriaComponent criteriaComponent = iterator.next();  | 
  |  578 |    0 |                if (!criteriaComponent.isSearchable()) { | 
  |  579 |    0 |                    continue;  | 
  |  580 |     | 
               }  | 
  |  581 |     | 
     | 
  |  582 |    0 |                SqlBuilder sqlBuild = this.getSqlBuilder();  | 
  |  583 |     | 
     | 
  |  584 |    0 |                SearchableAttributeValue searchAttribute = criteriaComponent.getSearchableAttributeValue();  | 
  |  585 |    0 |                if (searchAttribute == null) { | 
  |  586 |     | 
                     | 
  |  587 |    0 |                    String errorMsg = "The search attribute value associated with key '" + criteriaComponent.getSavedKey() + "' cannot be found";  | 
  |  588 |    0 |                    LOG.error("getSearchableAttributeSql() " + errorMsg); | 
  |  589 |    0 |                    throw new RuntimeException(errorMsg);  | 
  |  590 |     | 
               }  | 
  |  591 |     | 
     | 
  |  592 |    0 |                tableAlias = "EXT" + tableIndex;  | 
  |  593 |     | 
     | 
  |  594 |    0 |                Class c = getSearchableAttributeClass(searchAttribute);  | 
  |  595 |     | 
     | 
  |  596 |    0 |                boolean addCaseInsensitivityForValue = (!criteriaComponent.isCaseSensitive()) && criteriaComponent.getSearchableAttributeValue().allowsCaseInsensitivity();  | 
  |  597 |     | 
     | 
  |  598 |    0 |                Criteria crit = null;  | 
  |  599 |    0 |                List<String> searchValues = criteriaComponent.getValues();  | 
  |  600 |    0 |                if (searchValues != null && !searchValues.isEmpty()) { | 
  |  601 |    0 |                    crit = new Criteria(searchAttribute.getAttributeTableName(), tableAlias);  | 
  |  602 |    0 |                    crit.setDbPlatform(sqlBuild.getDbPlatform());  | 
  |  603 |    0 |                    crit.in("VAL", criteriaComponent.getValues(), c); | 
  |  604 |     | 
               } else { | 
  |  605 |    0 |                    crit = sqlBuild.createCriteria("VAL", criteriaComponent.getValue() , searchAttribute.getAttributeTableName(), tableAlias, c, addCaseInsensitivityForValue, searchAttribute.allowsWildcards()); | 
  |  606 |     | 
               }  | 
  |  607 |    0 |                sqlBuild.addCriteria("KEY_CD", criteriaComponent.getSavedKey(), String.class, false, false, crit);  | 
  |  608 |    0 |                sqlBuild.andCriteria("DOC_HDR_ID", tableAlias + ".DOC_HDR_ID", "KREW_DOC_HDR_T", "DOC_HDR", TypeUtils.JoinType.class, false, false, crit); | 
  |  609 |     | 
     | 
  |  610 |    0 |                if(finalCriteria == null ){ | 
  |  611 |    0 |                    finalCriteria = crit;  | 
  |  612 |     | 
               }else{ | 
  |  613 |    0 |                    sqlBuild.andCriteria(finalCriteria, crit);  | 
  |  614 |     | 
               }  | 
  |  615 |     | 
     | 
  |  616 |     | 
                 | 
  |  617 |     | 
                 | 
  |  618 |    0 |                String whereClausePrefix = (whereSql.length() == 0) ? whereClausePredicatePrefix : getGeneratedPredicatePrefix(whereSql.length());  | 
  |  619 |    0 |                QueryComponent qc = generateSearchableAttributeSql(criteriaComponent, whereClausePrefix, tableIndex);  | 
  |  620 |    0 |                fromSql.append(qc.getFromSql());  | 
  |  621 |     | 
     | 
  |  622 |     | 
           }  | 
  |  623 |     | 
     | 
  |  624 |    0 |            for (String keyName : searchableAttributeRangeComponents.keySet()) { | 
  |  625 |    0 |                List<SearchAttributeCriteriaComponent> criteriaComponents = searchableAttributeRangeComponents.get(keyName);  | 
  |  626 |     | 
                 | 
  |  627 |    0 |                String whereClausePrefix = (whereSql.length() == 0) ? whereClausePredicatePrefix : getGeneratedPredicatePrefix(whereSql.length());  | 
  |  628 |    0 |                QueryComponent qc = generateSearchableAttributeRangeSql(keyName, criteriaComponents, whereClausePrefix, tableIndex);  | 
  |  629 |    0 |                fromSql.append(qc.getFromSql());  | 
  |  630 |    0 |            }  | 
  |  631 |     | 
             | 
  |  632 |    0 |            if (finalCriteria == null) { | 
  |  633 |    0 |                return new QueryComponent("", "", ""); | 
  |  634 |     | 
           }  | 
  |  635 |     | 
     | 
  |  636 |    0 |            String whereClausePrefix = (whereSql.length() == 0) ? whereClausePredicatePrefix : getGeneratedPredicatePrefix(whereSql.length());  | 
  |  637 |     | 
     | 
  |  638 |    0 |            return new QueryComponent("",fromSql.toString(),whereClausePrefix + " "+ finalCriteria.buildWhere()); | 
  |  639 |     | 
       }  | 
  |  640 |     | 
     | 
  |  641 |     | 
       public QueryComponent generateSearchableAttributeSql(SearchAttributeCriteriaComponent criteriaComponent,String whereSqlStarter,int tableIndex) { | 
  |  642 |    0 |            String tableIdentifier = "EXT" + tableIndex;  | 
  |  643 |    0 |            String queryTableColumnName = tableIdentifier + ".VAL";  | 
  |  644 |    0 |            QueryComponent joinSqlComponent = getSearchableAttributeJoinSql(criteriaComponent.getSearchableAttributeValue(), tableIdentifier, whereSqlStarter, criteriaComponent.getSavedKey());  | 
  |  645 |    0 |            StringBuffer fromSql = new StringBuffer(joinSqlComponent.getFromSql());  | 
  |  646 |    0 |            StringBuffer whereSql = new StringBuffer(joinSqlComponent.getWhereSql());  | 
  |  647 |     | 
     | 
  |  648 |     | 
             | 
  |  649 |     | 
             | 
  |  650 |     | 
     | 
  |  651 |    0 |            return new QueryComponent("",fromSql.toString(),whereSql.toString()); | 
  |  652 |     | 
       }  | 
  |  653 |     | 
     | 
  |  654 |     | 
       public QueryComponent generateSearchableAttributeRangeSql(String searchAttributeKeyName, List<SearchAttributeCriteriaComponent> criteriaComponents,String whereSqlStarter,int tableIndex) { | 
  |  655 |    0 |            StringBuffer fromSql = new StringBuffer();  | 
  |  656 |    0 |            StringBuffer whereSql = new StringBuffer();  | 
  |  657 |    0 |            boolean joinAlreadyPerformed = false;  | 
  |  658 |    0 |            String tableIdentifier = "EXT" + tableIndex;  | 
  |  659 |    0 |            String queryTableColumnName = tableIdentifier + ".VAL";  | 
  |  660 |     | 
     | 
  |  661 |    0 |            for (SearchAttributeCriteriaComponent criteriaComponent : criteriaComponents) { | 
  |  662 |    0 |                if (!searchAttributeKeyName.equals(criteriaComponent.getSavedKey())) { | 
  |  663 |    0 |                    String errorMsg = "Key value of searchable attribute component with savedKey '" + criteriaComponent.getSavedKey() + "' does not match specified savedKey value '" + searchAttributeKeyName + "'";  | 
  |  664 |    0 |                    LOG.error("generateSearchableAttributeRangeSql() " + errorMsg); | 
  |  665 |    0 |                    throw new RuntimeException(errorMsg);  | 
  |  666 |     | 
               }  | 
  |  667 |    0 |                if (!joinAlreadyPerformed) { | 
  |  668 |    0 |                    QueryComponent joinSqlComponent = getSearchableAttributeJoinSql(criteriaComponent.getSearchableAttributeValue(), tableIdentifier, whereSqlStarter, searchAttributeKeyName);  | 
  |  669 |    0 |                    fromSql.append(joinSqlComponent.getFromSql());  | 
  |  670 |    0 |                    whereSql.append(joinSqlComponent.getWhereSql());  | 
  |  671 |    0 |                    joinAlreadyPerformed = true;  | 
  |  672 |     | 
               }  | 
  |  673 |    0 |                whereSql.append(generateSearchableAttributeDefaultWhereSql(criteriaComponent, queryTableColumnName));  | 
  |  674 |     | 
           }  | 
  |  675 |     | 
     | 
  |  676 |    0 |            return new QueryComponent("",fromSql.toString(),whereSql.toString()); | 
  |  677 |     | 
       }  | 
  |  678 |     | 
     | 
  |  679 |     | 
       public StringBuilder generateSearchableAttributeDefaultWhereSql(SearchAttributeCriteriaComponent criteriaComponent,String queryTableColumnName) { | 
  |  680 |    0 |            StringBuilder whereSql = new StringBuilder();  | 
  |  681 |    0 |            String initialClauseStarter = "and";  | 
  |  682 |     | 
     | 
  |  683 |     | 
     | 
  |  684 |    0 |            boolean valueIsDate = (criteriaComponent.getSearchableAttributeValue() instanceof SearchableAttributeDateTimeValue);  | 
  |  685 |    0 |            boolean valueIsString = (criteriaComponent.getSearchableAttributeValue() instanceof SearchableAttributeStringValue);  | 
  |  686 |    0 |            boolean valueIsLong = (criteriaComponent.getSearchableAttributeValue() instanceof SearchableAttributeLongValue);  | 
  |  687 |    0 |            boolean valueIsFloat = (criteriaComponent.getSearchableAttributeValue() instanceof SearchableAttributeFloatValue);  | 
  |  688 |    0 |            boolean addCaseInsensitivityForValue = (!criteriaComponent.isCaseSensitive()) && criteriaComponent.getSearchableAttributeValue().allowsCaseInsensitivity();  | 
  |  689 |    0 |            String attributeValueSearched = criteriaComponent.getValue();  | 
  |  690 |    0 |            List<String> attributeValuesSearched = criteriaComponent.getValues();  | 
  |  691 |     | 
     | 
  |  692 |    0 |            StringBuilder whereSqlTemp = new StringBuilder();  | 
  |  693 |    0 |            if (valueIsDate) { | 
  |  694 |    0 |                if (criteriaComponent.isRangeSearch()) { | 
  |  695 |     | 
                     | 
  |  696 |    0 |                    whereSqlTemp.append(constructWhereClauseDateElement(initialClauseStarter, queryTableColumnName, criteriaComponent.isSearchInclusive(), criteriaComponent.isComponentLowerBoundValue(), attributeValueSearched));  | 
  |  697 |    0 |                } else if(criteriaComponent.isAllowInlineRange()) { | 
  |  698 |    0 |                    whereSqlTemp.append(constructWhereClauseDateElement(initialClauseStarter, queryTableColumnName, criteriaComponent.isSearchInclusive(), false, attributeValueSearched, criteriaComponent.isAllowInlineRange()));  | 
  |  699 |     | 
               } else { | 
  |  700 |    0 |                    if (!CollectionUtils.isEmpty(attributeValuesSearched)) { | 
  |  701 |     | 
                         | 
  |  702 |    0 |                        whereSqlTemp.append(initialClauseStarter).append(" ("); | 
  |  703 |    0 |                        boolean firstValue = true;  | 
  |  704 |    0 |                        for (String attributeValueEntered : attributeValuesSearched) { | 
  |  705 |    0 |                            whereSqlTemp.append(" ( "); | 
  |  706 |    0 |                            whereSqlTemp.append(constructWhereClauseDateElement("", queryTableColumnName, criteriaComponent.isSearchInclusive(), true, attributeValueEntered)); | 
  |  707 |    0 |                            whereSqlTemp.append(constructWhereClauseDateElement("and", queryTableColumnName, criteriaComponent.isSearchInclusive(), false, attributeValueEntered)); | 
  |  708 |    0 |                            whereSqlTemp.append(" ) "); | 
  |  709 |    0 |                            String separator = " or ";  | 
  |  710 |    0 |                            if (firstValue) { | 
  |  711 |    0 |                                firstValue = false;  | 
  |  712 |    0 |                                separator = "";  | 
  |  713 |     | 
                           }  | 
  |  714 |    0 |                            whereSqlTemp.append(separator);  | 
  |  715 |    0 |                        }  | 
  |  716 |    0 |                        whereSqlTemp.append(") "); | 
  |  717 |    0 |                    } else { | 
  |  718 |     | 
                         | 
  |  719 |    0 |                        whereSqlTemp.append(constructWhereClauseDateElement(initialClauseStarter, queryTableColumnName, criteriaComponent.isSearchInclusive(), true, attributeValueSearched));  | 
  |  720 |    0 |                        whereSqlTemp.append(constructWhereClauseDateElement(initialClauseStarter, queryTableColumnName, criteriaComponent.isSearchInclusive(), false, attributeValueSearched));  | 
  |  721 |     | 
                   }  | 
  |  722 |     | 
               }  | 
  |  723 |     | 
           } else { | 
  |  724 |    0 |                boolean usingWildcards = false;  | 
  |  725 |    0 |                StringBuffer prefix = new StringBuffer(""); | 
  |  726 |    0 |                StringBuffer suffix = new StringBuffer(""); | 
  |  727 |    0 |                if (valueIsString) { | 
  |  728 |    0 |                    prefix.append("'"); | 
  |  729 |    0 |                    suffix.insert(0,"'");  | 
  |  730 |     | 
               }  | 
  |  731 |     | 
                 | 
  |  732 |     | 
                 | 
  |  733 |    0 |                if (!CollectionUtils.isEmpty(attributeValuesSearched)) { | 
  |  734 |    0 |                    List<String> newList = new ArrayList<String>();  | 
  |  735 |    0 |                    for (String attributeValueEntered : attributeValuesSearched) { | 
  |  736 |    0 |                        newList.add(attributeValueEntered.trim().replace('*', DATABASE_WILDCARD_CHARACTER)); | 
  |  737 |    0 |                        usingWildcards |= (attributeValueEntered.contains(DATABASE_WILDCARD_CHARACTER_STRING));  | 
  |  738 |     | 
                   }  | 
  |  739 |    0 |                    attributeValuesSearched = newList;  | 
  |  740 |    0 |                } else { | 
  |  741 |    0 |                    attributeValueSearched = attributeValueSearched.trim().replace('*', DATABASE_WILDCARD_CHARACTER); | 
  |  742 |    0 |                    usingWildcards |= (attributeValueSearched.indexOf(DATABASE_WILDCARD_CHARACTER_STRING) != -1);  | 
  |  743 |     | 
               }  | 
  |  744 |    0 |                String prefixToUse = prefix.toString();  | 
  |  745 |    0 |                String suffixToUse = suffix.toString();  | 
  |  746 |     | 
     | 
  |  747 |    0 |                if (addCaseInsensitivityForValue) { | 
  |  748 |    0 |                    queryTableColumnName = "upper(" + queryTableColumnName + ")"; | 
  |  749 |    0 |                    prefixToUse = "upper(" + prefix.toString(); | 
  |  750 |    0 |                    suffixToUse = suffix.toString() + ")";  | 
  |  751 |     | 
               }  | 
  |  752 |     | 
     | 
  |  753 |    0 |                if (!CollectionUtils.isEmpty(attributeValuesSearched)) { | 
  |  754 |     | 
                     | 
  |  755 |    0 |                    whereSqlTemp.append(initialClauseStarter).append(" ("); | 
  |  756 |    0 |                    boolean firstValue = true;  | 
  |  757 |    0 |                    for (String attributeValueEntered : attributeValuesSearched) { | 
  |  758 |    0 |                        checkNumberFormattingIfNumeric(attributeValueEntered, valueIsLong, valueIsFloat);  | 
  |  759 |     | 
     | 
  |  760 |    0 |                        String separator = " or ";  | 
  |  761 |    0 |                        if (firstValue) { | 
  |  762 |    0 |                            firstValue = false;  | 
  |  763 |    0 |                            separator = "";  | 
  |  764 |     | 
                       }  | 
  |  765 |    0 |                        String sqlOperand = getSqlOperand(criteriaComponent.isRangeSearch(), criteriaComponent.isSearchInclusive(), (criteriaComponent.isRangeSearch() && criteriaComponent.isComponentLowerBoundValue()), usingWildcards);  | 
  |  766 |    0 |                        whereSqlTemp.append(constructWhereClauseElement(separator, queryTableColumnName, sqlOperand, getDbPlatform().escapeString(attributeValueEntered), prefixToUse, suffixToUse));  | 
  |  767 |    0 |                    }  | 
  |  768 |    0 |                    whereSqlTemp.append(") "); | 
  |  769 |    0 |                } else { | 
  |  770 |    0 |                    String sqlOperand = getSqlOperand(criteriaComponent.isRangeSearch(), criteriaComponent.isSearchInclusive(), (criteriaComponent.isRangeSearch() && criteriaComponent.isComponentLowerBoundValue()), usingWildcards);  | 
  |  771 |    0 |                  if(criteriaComponent.isAllowInlineRange()) { | 
  |  772 |    0 |                    for (String range : KNSConstants.RANGE_CHARACTERS) { | 
  |  773 |    0 |                            int index = StringUtils.indexOf(attributeValueSearched, range);  | 
  |  774 |    0 |                        if(index != -1) { | 
  |  775 |    0 |                                sqlOperand=range;  | 
  |  776 |    0 |                                if(!StringUtils.equals(sqlOperand, "..")) { | 
  |  777 |    0 |                                    attributeValueSearched = StringUtils.remove(attributeValueSearched, range);  | 
  |  778 |     | 
     | 
  |  779 |     | 
                               } else { | 
  |  780 |    0 |                                    String[] rangeValues = StringUtils.split(attributeValueSearched, "..");  | 
  |  781 |    0 |                                    if(rangeValues!=null && rangeValues.length>1) { | 
  |  782 |    0 |                                        checkNumberFormattingIfNumeric(rangeValues[0], valueIsLong, valueIsFloat);  | 
  |  783 |     | 
     | 
  |  784 |     | 
                                         | 
  |  785 |    0 |                                        whereSqlTemp.append(constructWhereClauseElement(initialClauseStarter, queryTableColumnName, ">=", getDbPlatform().escapeString(rangeValues[0]), prefixToUse, suffixToUse));  | 
  |  786 |    0 |                                        attributeValueSearched = rangeValues[1];  | 
  |  787 |    0 |                                        sqlOperand = "<=";  | 
  |  788 |     | 
                                   } else { | 
  |  789 |    0 |                                        throw new RuntimeException("What to do here...Range search \"..\" without one element"); | 
  |  790 |     | 
                                   }  | 
  |  791 |     | 
                               }  | 
  |  792 |    0 |                                break;  | 
  |  793 |     | 
                           }  | 
  |  794 |     | 
                       }  | 
  |  795 |     | 
                 }  | 
  |  796 |    0 |                    checkNumberFormattingIfNumeric(attributeValueSearched, valueIsLong, valueIsFloat);  | 
  |  797 |    0 |                    whereSqlTemp.append(constructWhereClauseElement(initialClauseStarter, queryTableColumnName, sqlOperand, getDbPlatform().escapeString(attributeValueSearched), prefixToUse, suffixToUse));  | 
  |  798 |     | 
               }  | 
  |  799 |     | 
           }  | 
  |  800 |    0 |            whereSqlTemp.append(" "); | 
  |  801 |    0 |            return whereSql.append(whereSqlTemp);  | 
  |  802 |     | 
       }  | 
  |  803 |     | 
     | 
  |  804 |     | 
         | 
  |  805 |     | 
     | 
  |  806 |     | 
     | 
  |  807 |     | 
     | 
  |  808 |     | 
     | 
  |  809 |     | 
     | 
  |  810 |     | 
     | 
  |  811 |     | 
     | 
  |  812 |     | 
       private void checkNumberFormattingIfNumeric(String testValue, boolean valueIsLong, boolean valueIsFloat) { | 
  |  813 |    0 |            if (valueIsLong) { | 
  |  814 |    0 |                try { Long.parseLong(testValue.trim()); } | 
  |  815 |    0 |                catch (Exception exc) { throw new RiceRuntimeException("Invalid number format", exc); } | 
  |  816 |     | 
           }  | 
  |  817 |    0 |            if (valueIsFloat) { | 
  |  818 |    0 |                try { new BigDecimal(testValue.trim()); } | 
  |  819 |    0 |                catch (Exception exc) { throw new RiceRuntimeException("Invalid number format", exc); } | 
  |  820 |     | 
           }  | 
  |  821 |    0 |        }  | 
  |  822 |     | 
     | 
  |  823 |     | 
       public QueryComponent getSearchableAttributeJoinSql(SearchableAttributeValue attributeValue,String tableIdentifier,String whereSqlStarter,String attributeTableKeyColumnName) { | 
  |  824 |    0 |            return new QueryComponent("",generateSearchableAttributeFromSql(attributeValue, tableIdentifier).toString(),generateSearchableAttributeWhereClauseJoin(whereSqlStarter, tableIdentifier, attributeTableKeyColumnName).toString()); | 
  |  825 |     | 
       }  | 
  |  826 |     | 
     | 
  |  827 |     | 
       public StringBuffer generateSearchableAttributeWhereClauseJoin(String whereSqlStarter,String tableIdentifier,String attributeTableKeyColumnName) { | 
  |  828 |    0 |            StringBuffer whereSql = new StringBuffer(constructWhereClauseElement(whereSqlStarter, "DOC_HDR.DOC_HDR_ID", "=", getDbPlatform().escapeString(tableIdentifier + ".DOC_HDR_ID"), null, null));  | 
  |  829 |    0 |            whereSql.append(constructWhereClauseElement(" and ", tableIdentifier + ".KEY_CD", "=", getDbPlatform().escapeString(attributeTableKeyColumnName), "'", "'")); | 
  |  830 |    0 |            return whereSql;  | 
  |  831 |     | 
       }  | 
  |  832 |     | 
     | 
  |  833 |     | 
       public StringBuffer generateSearchableAttributeFromSql(SearchableAttributeValue attributeValue,String tableIdentifier) { | 
  |  834 |    0 |            StringBuffer fromSql = new StringBuffer();  | 
  |  835 |    0 |            String tableName = getDbPlatform().escapeString(attributeValue.getAttributeTableName());  | 
  |  836 |    0 |            if (StringUtils.isBlank(tableName)) { | 
  |  837 |    0 |                String errorMsg = "The table name associated with Searchable Attribute with class '" + attributeValue.getClass() + "' returns as '" + tableName + "'";  | 
  |  838 |    0 |                LOG.error("getSearchableAttributeSql() " + errorMsg); | 
  |  839 |    0 |                throw new RuntimeException(errorMsg);  | 
  |  840 |     | 
           }  | 
  |  841 |    0 |            fromSql.append(" ," + tableName + " " + getDbPlatform().escapeString(tableIdentifier) + " "); | 
  |  842 |    0 |            return fromSql;  | 
  |  843 |     | 
       }  | 
  |  844 |     | 
     | 
  |  845 |     | 
       public StringBuffer constructWhereClauseDateElement(String clauseStarter,String queryTableColumnName,boolean inclusive,boolean valueIsLowerBound,String dateValueToSearch) { | 
  |  846 |    0 |            return constructWhereClauseDateElement(clauseStarter, queryTableColumnName, inclusive, valueIsLowerBound, dateValueToSearch,false);  | 
  |  847 |     | 
       }  | 
  |  848 |     | 
     | 
  |  849 |     | 
       public StringBuffer constructWhereClauseDateElement(String clauseStarter,String queryTableColumnName,boolean inclusive,boolean valueIsLowerBound,String dateValueToSearch, boolean isAllowInlineRange) { | 
  |  850 |    0 |            StringBuffer whereSQLBuffer = new StringBuffer();  | 
  |  851 |    0 |            StringBuffer sqlOperand = new StringBuffer(getSqlOperand(true, inclusive, valueIsLowerBound, false));  | 
  |  852 |    0 |            String lowerTimeBound = "00:00:00";  | 
  |  853 |    0 |            String upperTimeBound = "23:59:59";  | 
  |  854 |     | 
     | 
  |  855 |    0 |            String timeValueToSearch = null;  | 
  |  856 |    0 |            if (valueIsLowerBound) { | 
  |  857 |    0 |                timeValueToSearch = lowerTimeBound;  | 
  |  858 |     | 
           } else { | 
  |  859 |    0 |                timeValueToSearch = upperTimeBound;  | 
  |  860 |     | 
           }  | 
  |  861 |     | 
     | 
  |  862 |    0 |            if(isAllowInlineRange) { | 
  |  863 |    0 |                for (String range : KNSConstants.RANGE_CHARACTERS) { | 
  |  864 |    0 |                    int index = StringUtils.indexOf(dateValueToSearch, range);  | 
  |  865 |    0 |                    if(index != -1) { | 
  |  866 |    0 |                        sqlOperand=new StringBuffer(range);  | 
  |  867 |    0 |                        if(!StringUtils.equals(sqlOperand.toString(), "..")) { | 
  |  868 |    0 |                            dateValueToSearch = StringUtils.remove(dateValueToSearch,range);  | 
  |  869 |    0 |                            if(StringUtils.equals(range, ">")) { | 
  |  870 |    0 |                                timeValueToSearch = upperTimeBound;  | 
  |  871 |    0 |                            } else if(StringUtils.equals(range, "<")){ | 
  |  872 |    0 |                                timeValueToSearch = lowerTimeBound;  | 
  |  873 |     | 
                           }  | 
  |  874 |     | 
                       }  else { | 
  |  875 |    0 |                            String[] rangeValues = StringUtils.split(dateValueToSearch, "..");  | 
  |  876 |    0 |                            if(rangeValues!=null && rangeValues.length>1) { | 
  |  877 |     | 
                                 | 
  |  878 |     | 
                                 | 
  |  879 |    0 |                                timeValueToSearch = lowerTimeBound;  | 
  |  880 |    0 |                                                            whereSQLBuffer.append(constructWhereClauseElement(clauseStarter, queryTableColumnName, ">=", getDbPlatform().getDateSQL(getDbPlatform().escapeString(SQLUtils.getSqlFormattedDate(rangeValues[0].trim())), timeValueToSearch.trim()), "", ""));  | 
  |  881 |     | 
     | 
  |  882 |    0 |                                dateValueToSearch = rangeValues[1];  | 
  |  883 |    0 |                                sqlOperand = new StringBuffer("<="); | 
  |  884 |    0 |                                timeValueToSearch = upperTimeBound;  | 
  |  885 |     | 
                           } else { | 
  |  886 |    0 |                                throw new RuntimeException("What to do here...Range search \"..\" without one element"); | 
  |  887 |     | 
                           }  | 
  |  888 |     | 
                       }  | 
  |  889 |    0 |                        break;  | 
  |  890 |     | 
                   }  | 
  |  891 |     | 
               }  | 
  |  892 |     | 
           }  | 
  |  893 |    0 |                    return whereSQLBuffer.append(constructWhereClauseElement(clauseStarter, queryTableColumnName, sqlOperand.toString(), getDbPlatform().getDateSQL(getDbPlatform().escapeString(SQLUtils.getSqlFormattedDate(dateValueToSearch.trim())), timeValueToSearch.trim()), "", ""));  | 
  |  894 |     | 
       }  | 
  |  895 |     | 
     | 
  |  896 |     | 
       public StringBuffer constructWhereClauseElement(String clauseStarter,String queryTableColumnName,String operand,String valueToSearch,String valuePrefix,String valueSuffix) { | 
  |  897 |    0 |            StringBuffer whereSql = new StringBuffer();  | 
  |  898 |    0 |            valuePrefix = (valuePrefix != null) ? valuePrefix : "";  | 
  |  899 |    0 |            valueSuffix = (valueSuffix != null) ? valueSuffix : "";  | 
  |  900 |    0 |            whereSql.append(" " + clauseStarter + " ").append(getDbPlatform().escapeString(queryTableColumnName)).append(" " + operand + " ").append(valuePrefix).append(valueToSearch).append(valueSuffix).append(" "); | 
  |  901 |    0 |            return whereSql;  | 
  |  902 |     | 
       }  | 
  |  903 |     | 
     | 
  |  904 |     | 
         | 
  |  905 |     | 
     | 
  |  906 |     | 
     | 
  |  907 |     | 
     | 
  |  908 |     | 
       public String getSqlOperand(boolean rangeSearch, boolean inclusive, boolean valueIsLowerBound, boolean usingWildcards) { | 
  |  909 |    0 |            StringBuffer sqlOperand = new StringBuffer("="); | 
  |  910 |    0 |            if (rangeSearch) { | 
  |  911 |    0 |                if (valueIsLowerBound) { | 
  |  912 |    0 |                    sqlOperand = new StringBuffer(">"); | 
  |  913 |     | 
               } else { | 
  |  914 |    0 |                    sqlOperand = new StringBuffer("<"); | 
  |  915 |     | 
               }  | 
  |  916 |    0 |                if (inclusive) { | 
  |  917 |    0 |                    sqlOperand.append("="); | 
  |  918 |     | 
               }  | 
  |  919 |     | 
     | 
  |  920 |    0 |            } else if (usingWildcards) { | 
  |  921 |    0 |                sqlOperand = new StringBuffer("like"); | 
  |  922 |     | 
           }  | 
  |  923 |    0 |            return sqlOperand.toString();  | 
  |  924 |     | 
       }  | 
  |  925 |     | 
     | 
  |  926 |     | 
         | 
  |  927 |     | 
     | 
  |  928 |     | 
     | 
  |  929 |     | 
       public List<DocSearchDTO> processResultSet(Statement searchAttributeStatement, ResultSet resultSet,DocSearchCriteriaDTO searchCriteria) throws SQLException { | 
  |  930 |    0 |            String principalId = null;  | 
  |  931 |    0 |            return processResultSet(searchAttributeStatement, resultSet, searchCriteria, principalId);  | 
  |  932 |     | 
       }  | 
  |  933 |     | 
     | 
  |  934 |     | 
     | 
  |  935 |     | 
         | 
  |  936 |     | 
     | 
  |  937 |     | 
     | 
  |  938 |     | 
     | 
  |  939 |     | 
     | 
  |  940 |     | 
     | 
  |  941 |     | 
       public List<DocSearchDTO> processResultSet(Statement searchAttributeStatement, ResultSet resultSet,DocSearchCriteriaDTO searchCriteria, String principalId) throws SQLException { | 
  |  942 |    0 |            setCriteria(searchCriteria);  | 
  |  943 |    0 |            int size = 0;  | 
  |  944 |    0 |            List<DocSearchDTO> docList = new ArrayList<DocSearchDTO>();  | 
  |  945 |    0 |            Map<Long, DocSearchDTO> resultMap = new HashMap<Long, DocSearchDTO>();  | 
  |  946 |    0 |            PerformanceLogger perfLog = new PerformanceLogger();  | 
  |  947 |    0 |            int iteration = 0;  | 
  |  948 |    0 |            boolean resultSetHasNext = resultSet.next();  | 
  |  949 |     | 
           while ( resultSetHasNext &&  | 
  |  950 |    0 |                    ( (searchCriteria.getThreshold() == null) || (resultMap.size() < searchCriteria.getThreshold().intValue()) ) &&  | 
  |  951 |     | 
                   ( (searchCriteria.getFetchLimit() == null) || (iteration < searchCriteria.getFetchLimit().intValue()) ) ) { | 
  |  952 |    0 |                iteration++;  | 
  |  953 |    0 |                DocSearchDTO docCriteriaDTO = processRow(searchAttributeStatement, resultSet);  | 
  |  954 |    0 |                docCriteriaDTO.setSuperUserSearch(getCriteria().getSuperUserSearch());  | 
  |  955 |    0 |                if (!resultMap.containsKey(docCriteriaDTO.getRouteHeaderId())) { | 
  |  956 |    0 |                    docList.add(docCriteriaDTO);  | 
  |  957 |    0 |                    resultMap.put(docCriteriaDTO.getRouteHeaderId(), docCriteriaDTO);  | 
  |  958 |    0 |                    size++;  | 
  |  959 |     | 
               } else { | 
  |  960 |     | 
                     | 
  |  961 |    0 |                    DocSearchDTO previousEntry = (DocSearchDTO)resultMap.get(docCriteriaDTO.getRouteHeaderId());  | 
  |  962 |    0 |                    handleMultipleDocumentRows(previousEntry, docCriteriaDTO);  | 
  |  963 |     | 
               }  | 
  |  964 |    0 |                resultSetHasNext = resultSet.next();  | 
  |  965 |    0 |            }  | 
  |  966 |     | 
             | 
  |  967 |     | 
     | 
  |  968 |     | 
     | 
  |  969 |     | 
     | 
  |  970 |     | 
     | 
  |  971 |     | 
     | 
  |  972 |     | 
     | 
  |  973 |     | 
     | 
  |  974 |     | 
     | 
  |  975 |    0 |            Set<String> initiatorPrincipalIdSet = new HashSet<String>();  | 
  |  976 |    0 |            for (DocSearchDTO docSearchRow : docList) { | 
  |  977 |    0 |                    initiatorPrincipalIdSet.add(docSearchRow.getInitiatorWorkflowId());  | 
  |  978 |     | 
           }  | 
  |  979 |    0 |            List<String> initiatorPrincipalIds = new ArrayList<String>();  | 
  |  980 |    0 |            initiatorPrincipalIds.addAll(initiatorPrincipalIdSet);  | 
  |  981 |    0 |            if(initiatorPrincipalIds != null && !initiatorPrincipalIds.isEmpty()){  | 
  |  982 |    0 |                    Map<String, KimEntityNamePrincipalNameInfo> entityNames = KIMServiceLocator.getIdentityService().getDefaultNamesForPrincipalIds(initiatorPrincipalIds);  | 
  |  983 |    0 |                    for (DocSearchDTO docSearchRow : docList) { | 
  |  984 |    0 |                            KimEntityNamePrincipalNameInfo name = entityNames.get(docSearchRow.getInitiatorWorkflowId());  | 
  |  985 |    0 |                            if (name != null) { | 
  |  986 |    0 |                                    docSearchRow.setInitiatorFirstName(name.getDefaultEntityName().getFirstName());  | 
  |  987 |    0 |                                    docSearchRow.setInitiatorLastName(name.getDefaultEntityName().getLastName());  | 
  |  988 |    0 |                                    docSearchRow.setInitiatorName(name.getDefaultEntityName().getFormattedName());  | 
  |  989 |    0 |                                    docSearchRow.setInitiatorNetworkId(name.getPrincipalName());  | 
  |  990 |    0 |                                            if (StringUtils.isNotBlank(name.getDefaultEntityName().getFormattedName())) { | 
  |  991 |    0 |                                                    docSearchRow.setInitiatorTransposedName(name.getDefaultEntityName().getFormattedName());  | 
  |  992 |    0 |                                            } else if (StringUtils.isNotBlank(name.getPrincipalName())) { | 
  |  993 |    0 |                                                    docSearchRow.setInitiatorTransposedName(name.getPrincipalName());  | 
  |  994 |     | 
                                           } else { | 
  |  995 |    0 |                                                    docSearchRow.setInitiatorTransposedName(docSearchRow.getInitiatorWorkflowId());  | 
  |  996 |     | 
                                           }  | 
  |  997 |     | 
                                     | 
  |  998 |    0 |                                    docSearchRow.setInitiatorEmailAddress(""); | 
  |  999 |     | 
                           }  | 
  |  1000 |    0 |                    }  | 
  |  1001 |     | 
           }  | 
  |  1002 |     | 
             | 
  |  1003 |     | 
     | 
  |  1004 |     | 
     | 
  |  1005 |    0 |            perfLog.log("Time to read doc search results.", true); | 
  |  1006 |     | 
             | 
  |  1007 |    0 |            criteria.setOverThreshold(resultSetHasNext);  | 
  |  1008 |     | 
     | 
  |  1009 |    0 |            final UserSession userSession = createUserSession(searchCriteria, principalId);  | 
  |  1010 |    0 |            if (userSession != null) { | 
  |  1011 |     | 
                 | 
  |  1012 |     | 
                 | 
  |  1013 |     | 
                 | 
  |  1014 |    0 |                perfLog = new PerformanceLogger();  | 
  |  1015 |    0 |                SecuritySession securitySession = new SecuritySession(userSession);  | 
  |  1016 |    0 |                for (Iterator<DocSearchDTO> iterator = docList.iterator(); iterator.hasNext();) { | 
  |  1017 |    0 |                    DocSearchDTO docCriteriaDTO = (DocSearchDTO) iterator.next();  | 
  |  1018 |    0 |                    if (!KEWServiceLocator.getDocumentSecurityService().docSearchAuthorized(userSession, docCriteriaDTO, securitySession)) { | 
  |  1019 |    0 |                        iterator.remove();  | 
  |  1020 |    0 |                        criteria.setSecurityFilteredRows(criteria.getSecurityFilteredRows() + 1);  | 
  |  1021 |     | 
                   }  | 
  |  1022 |    0 |                }  | 
  |  1023 |    0 |                perfLog.log("Time to filter document search results for security.", true); | 
  |  1024 |     | 
           }  | 
  |  1025 |     | 
     | 
  |  1026 |    0 |            LOG.debug("Processed "+size+" document search result rows."); | 
  |  1027 |    0 |            return docList;  | 
  |  1028 |     | 
       }  | 
  |  1029 |     | 
     | 
  |  1030 |     | 
       private static UserSession createUserSession(DocSearchCriteriaDTO searchCriteria, String principalId) { | 
  |  1031 |    0 |            UserSession userSession = GlobalVariables.getUserSession();  | 
  |  1032 |    0 |            if ( (userSession == null) && StringUtils.isNotBlank(principalId)) { | 
  |  1033 |    0 |                LOG.info("Authenticated User Session is null... using parameter user: " + principalId); | 
  |  1034 |    0 |                Person user = KIMServiceLocator.getPersonService().getPerson(principalId);  | 
  |  1035 |    0 |                if (user != null) { | 
  |  1036 |    0 |                        userSession = new UserSession(user.getPrincipalName());  | 
  |  1037 |     | 
               }  | 
  |  1038 |    0 |            } else if (searchCriteria.isOverridingUserSession()) { | 
  |  1039 |    0 |                if (principalId == null) { | 
  |  1040 |    0 |                    LOG.error("Search Criteria specified UserSession override but given user paramter is null"); | 
  |  1041 |    0 |                    throw new WorkflowRuntimeException("Search criteria specified UserSession override but given user is null."); | 
  |  1042 |     | 
               }  | 
  |  1043 |    0 |                LOG.info("Search Criteria specified UserSession override.  Using user: " + principalId); | 
  |  1044 |    0 |                Person user = KIMServiceLocator.getPersonService().getPerson(principalId);  | 
  |  1045 |    0 |                if (user != null) { | 
  |  1046 |    0 |                        userSession = new UserSession(user.getPrincipalName());  | 
  |  1047 |     | 
               }  | 
  |  1048 |     | 
           }  | 
  |  1049 |    0 |            return userSession;  | 
  |  1050 |     | 
       }  | 
  |  1051 |     | 
     | 
  |  1052 |     | 
         | 
  |  1053 |     | 
     | 
  |  1054 |     | 
     | 
  |  1055 |     | 
     | 
  |  1056 |     | 
     | 
  |  1057 |     | 
     | 
  |  1058 |     | 
     | 
  |  1059 |     | 
       public void handleMultipleDocumentRows(DocSearchDTO existingRow, DocSearchDTO newRow) { | 
  |  1060 |     | 
     | 
  |  1061 |    0 |            for (KeyValueSort newData : newRow.getSearchableAttributes()) { | 
  |  1062 |    0 |                String newRowValue = newData.getValue();  | 
  |  1063 |    0 |                boolean foundMatch = false;  | 
  |  1064 |    0 |                for (KeyValueSort existingData : existingRow.getSearchableAttributes()) { | 
  |  1065 |    0 |                    if (existingData.getKey().equals(newData.getKey())) { | 
  |  1066 |    0 |                        String existingRowValue = existingData.getValue();  | 
  |  1067 |    0 |                        if (!org.apache.commons.lang.StringUtils.isEmpty(newRowValue)) { | 
  |  1068 |    0 |                            String valueToSet = "";  | 
  |  1069 |    0 |                            if (org.apache.commons.lang.StringUtils.isEmpty(existingRowValue)) { | 
  |  1070 |    0 |                                valueToSet = newRowValue;  | 
  |  1071 |     | 
                           } else { | 
  |  1072 |    0 |                                valueToSet = existingRowValue + "<br>" + newRowValue;  | 
  |  1073 |     | 
                           }  | 
  |  1074 |    0 |                            existingData.setValue(valueToSet);  | 
  |  1075 |    0 |                            if ( (existingData.getSortValue() == null) && (newData.getSortValue() != null) ) { | 
  |  1076 |    0 |                                existingData.setSortValue(newData.getSortValue());  | 
  |  1077 |     | 
                           }  | 
  |  1078 |     | 
                       }  | 
  |  1079 |    0 |                        foundMatch = true;  | 
  |  1080 |    0 |                    }  | 
  |  1081 |     | 
               }  | 
  |  1082 |    0 |                if (!foundMatch) { | 
  |  1083 |    0 |                    existingRow.addSearchableAttribute(new KeyValueSort(newData));  | 
  |  1084 |     | 
               }  | 
  |  1085 |    0 |            }  | 
  |  1086 |    0 |        }  | 
  |  1087 |     | 
     | 
  |  1088 |     | 
       public DocSearchDTO processRow(Statement searchAttributeStatement, ResultSet rs) throws SQLException { | 
  |  1089 |    0 |            DocSearchDTO docCriteriaDTO = new DocSearchDTO();  | 
  |  1090 |     | 
     | 
  |  1091 |    0 |            docCriteriaDTO.setRouteHeaderId(new Long(rs.getLong("DOC_HDR_ID"))); | 
  |  1092 |     | 
     | 
  |  1093 |    0 |            String docTypeLabel = rs.getString("LBL"); | 
  |  1094 |    0 |            String activeIndicatorCode = rs.getString("ACTV_IND"); | 
  |  1095 |     | 
     | 
  |  1096 |    0 |            docCriteriaDTO.setDocRouteStatusCode(rs.getString("DOC_HDR_STAT_CD")); | 
  |  1097 |    0 |            docCriteriaDTO.setDateCreated(rs.getTimestamp("CRTE_DT")); | 
  |  1098 |    0 |            docCriteriaDTO.setDocumentTitle(rs.getString("TTL")); | 
  |  1099 |    0 |            docCriteriaDTO.setDocTypeName(rs.getString("DOC_TYP_NM")); | 
  |  1100 |    0 |            docCriteriaDTO.setDocTypeLabel(docTypeLabel);  | 
  |  1101 |    0 |            docCriteriaDTO.setAppDocStatus(rs.getString("APP_DOC_STAT")); | 
  |  1102 |     | 
     | 
  |  1103 |    0 |            if ((activeIndicatorCode == null) || (activeIndicatorCode.trim().length() == 0)) { | 
  |  1104 |    0 |                docCriteriaDTO.setActiveIndicatorCode(KEWConstants.ACTIVE_CD);  | 
  |  1105 |     | 
           } else { | 
  |  1106 |    0 |                docCriteriaDTO.setActiveIndicatorCode(activeIndicatorCode);  | 
  |  1107 |     | 
           }  | 
  |  1108 |     | 
     | 
  |  1109 |    0 |            if ((docTypeLabel == null) || (docTypeLabel.trim().length() == 0)) { | 
  |  1110 |    0 |                docCriteriaDTO.setDocTypeHandlerUrl(""); | 
  |  1111 |     | 
           } else { | 
  |  1112 |    0 |                docCriteriaDTO.setDocTypeHandlerUrl(rs.getString("DOC_HDLR_URL")); | 
  |  1113 |     | 
           }  | 
  |  1114 |     | 
     | 
  |  1115 |    0 |            docCriteriaDTO.setInitiatorWorkflowId(rs.getString("INITR_PRNCPL_ID")); | 
  |  1116 |     | 
     | 
  |  1117 |     | 
             | 
  |  1118 |     | 
     | 
  |  1119 |     | 
     | 
  |  1120 |     | 
     | 
  |  1121 |     | 
     | 
  |  1122 |     | 
     | 
  |  1123 |     | 
     | 
  |  1124 |     | 
     | 
  |  1125 |     | 
     | 
  |  1126 |     | 
     | 
  |  1127 |     | 
             | 
  |  1128 |     | 
     | 
  |  1129 |     | 
     | 
  |  1130 |     | 
     | 
  |  1131 |     | 
     | 
  |  1132 |     | 
     | 
  |  1133 |     | 
     | 
  |  1134 |     | 
     | 
  |  1135 |     | 
     | 
  |  1136 |     | 
     | 
  |  1137 |     | 
     | 
  |  1138 |     | 
     | 
  |  1139 |     | 
     | 
  |  1140 |     | 
     | 
  |  1141 |     | 
     | 
  |  1142 |     | 
     | 
  |  1143 |     | 
             | 
  |  1144 |     | 
     | 
  |  1145 |     | 
     | 
  |  1146 |     | 
             | 
  |  1147 |    0 |            if (isUsingAtLeastOneSearchAttribute()) { | 
  |  1148 |    0 |                populateRowSearchableAttributes(docCriteriaDTO,searchAttributeStatement);  | 
  |  1149 |     | 
           }  | 
  |  1150 |    0 |            return docCriteriaDTO;  | 
  |  1151 |     | 
       }  | 
  |  1152 |     | 
     | 
  |  1153 |     | 
         | 
  |  1154 |     | 
     | 
  |  1155 |     | 
     | 
  |  1156 |     | 
     | 
  |  1157 |     | 
     | 
  |  1158 |     | 
     | 
  |  1159 |     | 
     | 
  |  1160 |     | 
     | 
  |  1161 |     | 
       public void populateRowSearchableAttributes(DocSearchDTO docCriteriaDTO, Statement searchAttributeStatement) throws SQLException { | 
  |  1162 |    0 |            searchAttributeStatement.setFetchSize(50);  | 
  |  1163 |    0 |            Long documentId = docCriteriaDTO.getRouteHeaderId();  | 
  |  1164 |    0 |            List<SearchableAttributeValue> attributeValues = DocSearchUtils.getSearchableAttributeValueObjectTypes();  | 
  |  1165 |    0 |            PerformanceLogger perfLog = new PerformanceLogger(documentId);  | 
  |  1166 |    0 |            for (SearchableAttributeValue searchAttValue : attributeValues) { | 
  |  1167 |    0 |                String attributeSql = "select KEY_CD, VAL from " + searchAttValue.getAttributeTableName() + " where DOC_HDR_ID = " + documentId;  | 
  |  1168 |    0 |                ResultSet attributeResultSet = null;  | 
  |  1169 |     | 
               try { | 
  |  1170 |    0 |                    attributeResultSet = searchAttributeStatement.executeQuery(attributeSql);  | 
  |  1171 |    0 |                    while (attributeResultSet.next()) { | 
  |  1172 |    0 |                        searchAttValue.setSearchableAttributeKey(attributeResultSet.getString("KEY_CD")); | 
  |  1173 |    0 |                        searchAttValue.setupAttributeValue(attributeResultSet, "VAL");  | 
  |  1174 |    0 |                        if ( (!org.apache.commons.lang.StringUtils.isEmpty(searchAttValue.getSearchableAttributeKey())) && (searchAttValue.getSearchableAttributeValue() != null) ) { | 
  |  1175 |    0 |                            docCriteriaDTO.addSearchableAttribute(new KeyValueSort(searchAttValue.getSearchableAttributeKey(),searchAttValue.getSearchableAttributeDisplayValue(),searchAttValue.getSearchableAttributeValue(),searchAttValue));  | 
  |  1176 |     | 
                       }  | 
  |  1177 |     | 
                   }  | 
  |  1178 |     | 
               } finally { | 
  |  1179 |    0 |                    if (attributeResultSet != null) { | 
  |  1180 |     | 
                       try { | 
  |  1181 |    0 |                            attributeResultSet.close();  | 
  |  1182 |    0 |                        } catch (Exception e) { | 
  |  1183 |    0 |                            LOG.warn("Could not close searchable attribute result set for class " + searchAttValue.getClass().getName(),e); | 
  |  1184 |    0 |                        }  | 
  |  1185 |     | 
                   }  | 
  |  1186 |     | 
               }  | 
  |  1187 |    0 |            }  | 
  |  1188 |    0 |            perfLog.log("Time to execute doc search search attribute queries.", true); | 
  |  1189 |    0 |        }  | 
  |  1190 |     | 
     | 
  |  1191 |     | 
         | 
  |  1192 |     | 
     | 
  |  1193 |     | 
     | 
  |  1194 |     | 
     | 
  |  1195 |     | 
       @Deprecated  | 
  |  1196 |     | 
       public void populateRowSearchableAttributes(DocSearchDTO docCriteriaDTO, Statement searchAttributeStatement, ResultSet rs) throws SQLException { | 
  |  1197 |    0 |            List<SearchableAttributeValue> searchAttributeValues = DocSearchUtils.getSearchableAttributeValueObjectTypes();  | 
  |  1198 |    0 |            for (SearchableAttributeValue searchAttValue : searchAttributeValues) { | 
  |  1199 |    0 |                String prefixName = searchAttValue.getAttributeDataType().toUpperCase();  | 
  |  1200 |    0 |                searchAttValue.setSearchableAttributeKey(rs.getString(prefixName + "_KEY"));  | 
  |  1201 |    0 |                searchAttValue.setupAttributeValue(rs, prefixName + "_VALUE");  | 
  |  1202 |    0 |                if ( (!org.apache.commons.lang.StringUtils.isEmpty(searchAttValue.getSearchableAttributeKey())) && (searchAttValue.getSearchableAttributeValue() != null) ) { | 
  |  1203 |    0 |                docCriteriaDTO.addSearchableAttribute(new KeyValueSort(searchAttValue.getSearchableAttributeKey(),searchAttValue.getSearchableAttributeDisplayValue(),searchAttValue.getSearchableAttributeValue(),searchAttValue));  | 
  |  1204 |     | 
               }  | 
  |  1205 |    0 |            }  | 
  |  1206 |    0 |        }  | 
  |  1207 |     | 
     | 
  |  1208 |     | 
       public String getDocSearchSQL() { | 
  |  1209 |     | 
     | 
  |  1210 |    0 |            String docTypeTableAlias   = "DOC1";  | 
  |  1211 |    0 |            String docHeaderTableAlias = "DOC_HDR";  | 
  |  1212 |     | 
     | 
  |  1213 |    0 |            String sqlPrefix = "Select * from ("; | 
  |  1214 |    0 |            String sqlSuffix = ") FINAL_SEARCH order by FINAL_SEARCH.DOC_HDR_ID desc";  | 
  |  1215 |     | 
             | 
  |  1216 |    0 |            StringBuffer selectSQL = new StringBuffer("select DISTINCT("+ docHeaderTableAlias +".DOC_HDR_ID), "+ docHeaderTableAlias +".INITR_PRNCPL_ID, " | 
  |  1217 |     | 
                   + docHeaderTableAlias +".DOC_HDR_STAT_CD, "+ docHeaderTableAlias +".CRTE_DT, "+ docHeaderTableAlias +".TTL, "+ docHeaderTableAlias +".APP_DOC_STAT, "+ docTypeTableAlias +".DOC_TYP_NM, "  | 
  |  1218 |     | 
                   + docTypeTableAlias +".LBL, "+ docTypeTableAlias +".DOC_HDLR_URL, "+ docTypeTableAlias +".ACTV_IND");  | 
  |  1219 |    0 |            StringBuffer fromSQL = new StringBuffer(" from KREW_DOC_TYP_T "+ docTypeTableAlias +" "); | 
  |  1220 |    0 |            StringBuffer fromSQLForDocHeaderTable = new StringBuffer(", KREW_DOC_HDR_T " + docHeaderTableAlias + " "); | 
  |  1221 |     | 
     | 
  |  1222 |    0 |            StringBuffer whereSQL = new StringBuffer();  | 
  |  1223 |    0 |            whereSQL.append(getRouteHeaderIdSql(criteria.getRouteHeaderId(), getGeneratedPredicatePrefix(whereSQL.length()), docHeaderTableAlias));  | 
  |  1224 |    0 |            whereSQL.append(getInitiatorSql(criteria.getInitiator(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1225 |    0 |            whereSQL.append(getAppDocIdSql(criteria.getAppDocId(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1226 |    0 |            whereSQL.append(getDateCreatedSql(criteria.getFromDateCreated(), criteria.getToDateCreated(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1227 |    0 |            whereSQL.append(getDateLastModifiedSql(criteria.getFromDateLastModified(), criteria.getToDateLastModified(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1228 |    0 |            whereSQL.append(getDateApprovedSql(criteria.getFromDateApproved(), criteria.getToDateApproved(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1229 |    0 |            whereSQL.append(getDateFinalizedSql(criteria.getFromDateFinalized(), criteria.getToDateFinalized(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1230 |     | 
             | 
  |  1231 |    0 |            if ((!"".equals(getViewerSql(criteria.getViewer(), getGeneratedPredicatePrefix(whereSQL.length())))) || (!"".equals(getWorkgroupViewerSql(criteria.getWorkgroupViewerId(), criteria.getWorkgroupViewerName(), getGeneratedPredicatePrefix(whereSQL.length()))))) { | 
  |  1232 |    0 |                whereSQL.append(getViewerSql(criteria.getViewer(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1233 |    0 |                whereSQL.append(getWorkgroupViewerSql(criteria.getWorkgroupViewerId(), criteria.getWorkgroupViewerName(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1234 |    0 |                fromSQL.append(", KREW_ACTN_RQST_T "); | 
  |  1235 |     | 
           }  | 
  |  1236 |     | 
     | 
  |  1237 |    0 |            if (!("".equals(getApproverSql(criteria.getApprover(), getGeneratedPredicatePrefix(whereSQL.length()))))) { | 
  |  1238 |    0 |                whereSQL.append(getApproverSql(criteria.getApprover(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1239 |    0 |                fromSQL.append(", KREW_ACTN_TKN_T "); | 
  |  1240 |     | 
           }  | 
  |  1241 |     | 
     | 
  |  1242 |     | 
     | 
  |  1243 |     | 
     | 
  |  1244 |    0 |            String docRouteNodeSql = getDocRouteNodeSql(criteria.getDocTypeFullName(), criteria.getDocRouteNodeId(), criteria.getDocRouteNodeLogic(), getGeneratedPredicatePrefix(whereSQL.length()));  | 
  |  1245 |    0 |            if (!"".equals(docRouteNodeSql)) { | 
  |  1246 |    0 |                whereSQL.append(docRouteNodeSql);  | 
  |  1247 |    0 |                fromSQL.append(", KREW_RTE_NODE_INSTN_T "); | 
  |  1248 |    0 |                fromSQL.append(", KREW_RTE_NODE_T "); | 
  |  1249 |     | 
           }  | 
  |  1250 |     | 
     | 
  |  1251 |    0 |            filterOutNonQueryAttributes();  | 
  |  1252 |    0 |            if ((criteria.getSearchableAttributes() != null) && (criteria.getSearchableAttributes().size() > 0)) { | 
  |  1253 |    0 |                QueryComponent queryComponent = getSearchableAttributeSql(criteria.getSearchableAttributes(), getGeneratedPredicatePrefix(whereSQL.length()));  | 
  |  1254 |    0 |                selectSQL.append(queryComponent.getSelectSql());  | 
  |  1255 |    0 |                fromSQL.append(queryComponent.getFromSql());  | 
  |  1256 |    0 |                whereSQL.append(queryComponent.getWhereSql());  | 
  |  1257 |     | 
           }  | 
  |  1258 |     | 
     | 
  |  1259 |     | 
             | 
  |  1260 |     | 
             | 
  |  1261 |     | 
             | 
  |  1262 |    0 |            Integer defaultCreateDateDaysAgoValue = null;  | 
  |  1263 |     | 
     | 
  |  1264 |    0 |            String tempWhereSql = getDocTitleSql(criteria.getDocTitle(), getGeneratedPredicatePrefix(whereSQL.length()));  | 
  |  1265 |    0 |            if ( ((whereSQL == null) || (StringUtils.isBlank(whereSQL.toString()))) && (StringUtils.isNotBlank(tempWhereSql)) ) { | 
  |  1266 |     | 
                 | 
  |  1267 |    0 |                defaultCreateDateDaysAgoValue = KEWConstants.DOCUMENT_SEARCH_DOC_TITLE_CREATE_DATE_DAYS_AGO;  | 
  |  1268 |     | 
           }  | 
  |  1269 |    0 |            whereSQL.append(tempWhereSql);  | 
  |  1270 |    0 |            if ( ((whereSQL == null) || (StringUtils.isBlank(whereSQL.toString()))) && (StringUtils.isBlank(criteria.getDocRouteStatus())) ) { | 
  |  1271 |     | 
                 | 
  |  1272 |    0 |                defaultCreateDateDaysAgoValue = KEWConstants.DOCUMENT_SEARCH_NO_CRITERIA_CREATE_DATE_DAYS_AGO;  | 
  |  1273 |     | 
           }  | 
  |  1274 |    0 |            if (defaultCreateDateDaysAgoValue != null) { | 
  |  1275 |     | 
                 | 
  |  1276 |    0 |                Calendar calendar = Calendar.getInstance();  | 
  |  1277 |    0 |                calendar.add(Calendar.DATE, defaultCreateDateDaysAgoValue.intValue());  | 
  |  1278 |    0 |                criteria.setFromDateCreated(RiceConstants.getDefaultDateFormat().format(calendar.getTime()));  | 
  |  1279 |    0 |                whereSQL.append(getDateCreatedSql(criteria.getFromDateCreated(), criteria.getToDateCreated(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1280 |     | 
           }  | 
  |  1281 |     | 
     | 
  |  1282 |    0 |            String docTypeFullNameSql = getDocTypeFullNameWhereSql(criteria.getDocTypeFullName(), getGeneratedPredicatePrefix(whereSQL.length()));  | 
  |  1283 |    0 |            if (!("".equals(docTypeFullNameSql))) { | 
  |  1284 |    0 |                whereSQL.append(docTypeFullNameSql);  | 
  |  1285 |     | 
           }  | 
  |  1286 |    0 |            whereSQL.append(getDocRouteStatusSql(criteria.getDocRouteStatus(), getGeneratedPredicatePrefix(whereSQL.length())));  | 
  |  1287 |    0 |            whereSQL.append(getGeneratedPredicatePrefix(whereSQL.length())).append(" DOC_HDR.DOC_TYP_ID = DOC1.DOC_TYP_ID "); | 
  |  1288 |    0 |            fromSQL.append(fromSQLForDocHeaderTable);  | 
  |  1289 |     | 
             | 
  |  1290 |     | 
             | 
  |  1291 |    0 |            String statusTransitionWhereClause = getStatusTransitionDateSql(criteria.getFromStatusTransitionDate(), criteria.getToStatusTransitionDate(), getGeneratedPredicatePrefix(whereSQL.length()));  | 
  |  1292 |    0 |            whereSQL.append(getAppDocStatusSql(criteria.getAppDocStatus(), getGeneratedPredicatePrefix(whereSQL.length()), statusTransitionWhereClause.length() ));                  | 
  |  1293 |    0 |            if (statusTransitionWhereClause.length() > 0){ | 
  |  1294 |    0 |                    whereSQL.append(statusTransitionWhereClause);  | 
  |  1295 |    0 |                whereSQL.append(getGeneratedPredicatePrefix(whereSQL.length())).append(" DOC_HDR.DOC_HDR_ID = STAT_TRAN.DOC_HDR_ID "); | 
  |  1296 |    0 |                    fromSQL.append(", KREW_APP_DOC_STAT_TRAN_T STAT_TRAN "); | 
  |  1297 |     | 
           }   | 
  |  1298 |     | 
             | 
  |  1299 |    0 |            String finalizedSql = sqlPrefix + " " + selectSQL.toString() + " " + fromSQL.toString() + " " + whereSQL.toString() + " " + sqlSuffix;  | 
  |  1300 |     | 
     | 
  |  1301 |    0 |            LOG.info("*********** SEARCH SQL ***************"); | 
  |  1302 |    0 |            LOG.info(finalizedSql);  | 
  |  1303 |    0 |            LOG.info("**************************************"); | 
  |  1304 |    0 |            return finalizedSql;  | 
  |  1305 |     | 
       }  | 
  |  1306 |     | 
     | 
  |  1307 |     | 
         | 
  |  1308 |     | 
     | 
  |  1309 |     | 
     | 
  |  1310 |     | 
     | 
  |  1311 |     | 
     | 
  |  1312 |     | 
       @Deprecated  | 
  |  1313 |     | 
       public String generateFinalSQL(QueryComponent searchSQL,String docHeaderTableAlias, String standardSqlPrefix, String standardSqlSuffix) { | 
  |  1314 |    0 |            StringBuffer finalSql = new StringBuffer();  | 
  |  1315 |    0 |            List<SearchableAttributeValue> searchableAttributeValues = DocSearchUtils.getSearchableAttributeValueObjectTypes();  | 
  |  1316 |    0 |            List<String> tableAliasComponentNames = new ArrayList<String>(searchableAttributeValues.size());  | 
  |  1317 |    0 |            for (SearchableAttributeValue attValue : searchableAttributeValues) { | 
  |  1318 |    0 |                tableAliasComponentNames.add(attValue.getAttributeDataType().toUpperCase());  | 
  |  1319 |     | 
           }  | 
  |  1320 |    0 |            for (SearchableAttributeValue attributeValue : searchableAttributeValues) { | 
  |  1321 |    0 |                QueryComponent qc = generateSqlForSearchableAttributeValue(attributeValue, tableAliasComponentNames, docHeaderTableAlias);  | 
  |  1322 |    0 |                StringBuffer currentSql = new StringBuffer();  | 
  |  1323 |    0 |                currentSql.append(searchSQL.getSelectSql() + qc.getSelectSql() + searchSQL.getFromSql() + qc.getFromSql() + searchSQL.getWhereSql() + qc.getWhereSql());  | 
  |  1324 |    0 |                if (finalSql.length() == 0) { | 
  |  1325 |    0 |                    finalSql.append(standardSqlPrefix).append(" ( ").append(currentSql); | 
  |  1326 |     | 
               } else { | 
  |  1327 |    0 |                    finalSql.append(" ) UNION ( " + currentSql.toString()); | 
  |  1328 |     | 
               }  | 
  |  1329 |    0 |            }  | 
  |  1330 |    0 |            finalSql.append(" ) " + standardSqlSuffix); | 
  |  1331 |    0 |            return finalSql.toString();  | 
  |  1332 |     | 
       }  | 
  |  1333 |     | 
     | 
  |  1334 |     | 
         | 
  |  1335 |     | 
     | 
  |  1336 |     | 
     | 
  |  1337 |     | 
     | 
  |  1338 |     | 
     | 
  |  1339 |     | 
     | 
  |  1340 |     | 
       @Deprecated  | 
  |  1341 |     | 
       public QueryComponent generateSqlForSearchableAttributeValue(SearchableAttributeValue attributeValue, List<String> tableAliasComponentNames, String docHeaderTableAlias) { | 
  |  1342 |    0 |            StringBuffer selectSql = new StringBuffer();  | 
  |  1343 |    0 |            StringBuffer fromSql = new StringBuffer();  | 
  |  1344 |    0 |            String currentAttributeTableAlias = "SA_" + attributeValue.getAttributeDataType().toUpperCase();  | 
  |  1345 |    0 |            fromSql.append(" LEFT OUTER JOIN " + attributeValue.getAttributeTableName() + " " + currentAttributeTableAlias + " ON (" + docHeaderTableAlias + ".DOC_HDR_ID = " + currentAttributeTableAlias + ".DOC_HDR_ID)"); | 
  |  1346 |    0 |            for (String string : tableAliasComponentNames) { | 
  |  1347 |    0 |                String aliasComponentName = (String) string;  | 
  |  1348 |    0 |                if (aliasComponentName.equalsIgnoreCase(attributeValue.getAttributeDataType())) { | 
  |  1349 |    0 |                    selectSql.append(", " + currentAttributeTableAlias + ".KEY_CD as " + aliasComponentName + "_KEY, " + currentAttributeTableAlias + ".VAL as " + aliasComponentName + "_VALUE"); | 
  |  1350 |     | 
               } else { | 
  |  1351 |    0 |                    selectSql.append(", NULL as " + aliasComponentName + "_KEY, NULL as " + aliasComponentName + "_VALUE"); | 
  |  1352 |     | 
               }  | 
  |  1353 |    0 |            }  | 
  |  1354 |    0 |            return new QueryComponent(selectSql.toString(),fromSql.toString(),"");  | 
  |  1355 |     | 
       }  | 
  |  1356 |     | 
     | 
  |  1357 |     | 
       public String getRouteHeaderIdSql(String routeHeaderId, String whereClausePredicatePrefix, String tableAlias) { | 
  |  1358 |     | 
     | 
  |  1359 |    0 |            if ((routeHeaderId == null) || "".equals(routeHeaderId.trim())) { | 
  |  1360 |    0 |                return "";  | 
  |  1361 |     | 
           } else { | 
  |  1362 |    0 |                Criteria crit = getSqlBuilder().createCriteria("DOC_HDR_ID", routeHeaderId, "KREW_DOC_HDR_T", tableAlias,Long.TYPE); | 
  |  1363 |    0 |                return new StringBuffer(whereClausePredicatePrefix + crit.buildWhere()).toString();  | 
  |  1364 |     | 
           }  | 
  |  1365 |     | 
     | 
  |  1366 |     | 
       }  | 
  |  1367 |     | 
     | 
  |  1368 |     | 
       public String getInitiatorSql(String initiator, String whereClausePredicatePrefix) { | 
  |  1369 |    0 |            String tableAlias = "DOC_HDR";  | 
  |  1370 |     | 
     | 
  |  1371 |    0 |            if ((initiator == null) || "".equals(initiator.trim())) { | 
  |  1372 |    0 |                return "";  | 
  |  1373 |     | 
           }  | 
  |  1374 |     | 
     | 
  |  1375 |    0 |            Map<String, String> m = new HashMap<String, String>();  | 
  |  1376 |    0 |            m.put("principalName", initiator); | 
  |  1377 |     | 
     | 
  |  1378 |     | 
             | 
  |  1379 |    0 |            List<Person> pList = KIMServiceLocator.getPersonService().findPeople(m, false);  | 
  |  1380 |     | 
     | 
  |  1381 |    0 |            if(pList == null || pList.isEmpty() ){ | 
  |  1382 |     | 
                 | 
  |  1383 |    0 |                 return new StringBuffer(whereClausePredicatePrefix + " 1 = 0 ").toString();  | 
  |  1384 |     | 
           }  | 
  |  1385 |     | 
     | 
  |  1386 |    0 |            List<String> principalList = new ArrayList<String>();  | 
  |  1387 |     | 
     | 
  |  1388 |    0 |            for(Person p: pList){ | 
  |  1389 |    0 |                principalList.add(p.getPrincipalId());  | 
  |  1390 |     | 
           }  | 
  |  1391 |     | 
     | 
  |  1392 |    0 |            Criteria crit = new Criteria("KREW_DOC_HDR_T", tableAlias); | 
  |  1393 |    0 |            crit.in("INITR_PRNCPL_ID", principalList, String.class); | 
  |  1394 |     | 
     | 
  |  1395 |     | 
             | 
  |  1396 |    0 |            return new StringBuffer(whereClausePredicatePrefix + crit.buildWhere()).toString();  | 
  |  1397 |     | 
     | 
  |  1398 |     | 
             | 
  |  1399 |     | 
       }  | 
  |  1400 |     | 
     | 
  |  1401 |     | 
       public String getDocTitleSql(String docTitle, String whereClausePredicatePrefix) { | 
  |  1402 |    0 |            if (StringUtils.isBlank(docTitle)) { | 
  |  1403 |    0 |                return "";  | 
  |  1404 |     | 
           } else { | 
  |  1405 |     | 
                 | 
  |  1406 |     | 
     | 
  |  1407 |     | 
     | 
  |  1408 |     | 
     | 
  |  1409 |     | 
     | 
  |  1410 |     | 
     | 
  |  1411 |     | 
     | 
  |  1412 |     | 
                 | 
  |  1413 |    0 |                docTitle = docTitle.trim().replace("\'", "\'\'"); | 
  |  1414 |     | 
     | 
  |  1415 |     | 
     | 
  |  1416 |    0 |                SqlBuilder sqlBuild = new SqlBuilder();  | 
  |  1417 |    0 |                Criteria crit = new Criteria("KREW_DOC_HDR_T", "DOC_HDR"); | 
  |  1418 |     | 
     | 
  |  1419 |    0 |                sqlBuild.addCriteria("TTL", docTitle, String.class, true, true, crit); | 
  |  1420 |    0 |                return new StringBuffer(whereClausePredicatePrefix + crit.buildWhere()).toString();  | 
  |  1421 |     | 
     | 
  |  1422 |     | 
     | 
  |  1423 |     | 
     | 
  |  1424 |     | 
                 | 
  |  1425 |     | 
           }  | 
  |  1426 |     | 
       }  | 
  |  1427 |     | 
     | 
  |  1428 |     | 
         | 
  |  1429 |     | 
         | 
  |  1430 |     | 
       public String getAppDocIdSql(String appDocId, String whereClausePredicatePrefix) { | 
  |  1431 |    0 |            String tableAlias = "DOC_HDR";  | 
  |  1432 |     | 
     | 
  |  1433 |    0 |            if ((appDocId == null) || "".equals(appDocId.trim())) { | 
  |  1434 |    0 |                return "";  | 
  |  1435 |     | 
           } else { | 
  |  1436 |    0 |                Criteria crit = getSqlBuilder().createCriteria("APP_DOC_ID", appDocId, "KREW_DOC_HDR_T", tableAlias,String.class); | 
  |  1437 |    0 |                return new StringBuffer(whereClausePredicatePrefix + crit.buildWhere()).toString();  | 
  |  1438 |     | 
           }  | 
  |  1439 |     | 
       }  | 
  |  1440 |     | 
     | 
  |  1441 |     | 
       public String getDateCreatedSql(String fromDateCreated, String toDateCreated, String whereClausePredicatePrefix) { | 
  |  1442 |    0 |            return establishDateString(fromDateCreated, toDateCreated, "KREW_DOC_HDR_T", "DOC_HDR", "CRTE_DT", whereClausePredicatePrefix);  | 
  |  1443 |     | 
       }  | 
  |  1444 |     | 
     | 
  |  1445 |     | 
       public String getDateApprovedSql(String fromDateApproved, String toDateApproved, String whereClausePredicatePrefix) { | 
  |  1446 |    0 |            return establishDateString(fromDateApproved, toDateApproved, "KREW_DOC_HDR_T", "DOC_HDR", "APRV_DT", whereClausePredicatePrefix);  | 
  |  1447 |     | 
       }  | 
  |  1448 |     | 
     | 
  |  1449 |     | 
       public String getDateFinalizedSql(String fromDateFinalized, String toDateFinalized, String whereClausePredicatePrefix) { | 
  |  1450 |    0 |            return establishDateString(fromDateFinalized, toDateFinalized, "KREW_DOC_HDR_T", "DOC_HDR", "FNL_DT", whereClausePredicatePrefix);  | 
  |  1451 |     | 
     | 
  |  1452 |     | 
       }  | 
  |  1453 |     | 
     | 
  |  1454 |     | 
       public String getDateLastModifiedSql(String fromDateLastModified, String toDateLastModified, String whereClausePredicatePrefix) { | 
  |  1455 |    0 |            return establishDateString(fromDateLastModified, toDateLastModified, "KREW_DOC_HDR_T", "DOC_HDR", "STAT_MDFN_DT", whereClausePredicatePrefix);  | 
  |  1456 |     | 
       }  | 
  |  1457 |     | 
     | 
  |  1458 |     | 
           public String getStatusTransitionDateSql(String fromStatusTransitionDate, String toStatusTransitionDate, String whereClausePredicatePrefix) { | 
  |  1459 |    0 |            return establishDateString(fromStatusTransitionDate, toStatusTransitionDate, "KREW_DOC_HDR_T", "DOC_HDR", "APP_DOC_STAT_MDFN_DT", whereClausePredicatePrefix);  | 
  |  1460 |     | 
       }  | 
  |  1461 |     | 
         | 
  |  1462 |     | 
       public String getViewerSql(String viewer, String whereClausePredicatePrefix) { | 
  |  1463 |    0 |            String returnSql = "";  | 
  |  1464 |    0 |            if ((viewer != null) && (!"".equals(viewer.trim()))) { | 
  |  1465 |    0 |                Map<String, String> m = new HashMap<String, String>();  | 
  |  1466 |    0 |                m.put("principalName", viewer); | 
  |  1467 |     | 
     | 
  |  1468 |     | 
                 | 
  |  1469 |    0 |                List<Person> pList = KIMServiceLocator.getPersonService().findPeople(m, false);  | 
  |  1470 |     | 
     | 
  |  1471 |    0 |                if(pList == null || pList.isEmpty() ){ | 
  |  1472 |     | 
                     | 
  |  1473 |    0 |                    return new StringBuffer(whereClausePredicatePrefix + " 1 = 0 ").toString();  | 
  |  1474 |     | 
               }  | 
  |  1475 |     | 
     | 
  |  1476 |    0 |                List<String> principalList = new ArrayList<String>();  | 
  |  1477 |     | 
     | 
  |  1478 |    0 |                for(Person p: pList){ | 
  |  1479 |    0 |                    principalList.add(p.getPrincipalId());  | 
  |  1480 |     | 
               }  | 
  |  1481 |     | 
     | 
  |  1482 |    0 |                Criteria crit = new Criteria("KREW_ACTN_RQST_T", "KREW_ACTN_RQST_T"); | 
  |  1483 |     | 
     | 
  |  1484 |    0 |                crit.in("PRNCPL_ID", principalList, String.class); | 
  |  1485 |     | 
     | 
  |  1486 |     | 
                 | 
  |  1487 |     | 
                 | 
  |  1488 |    0 |                returnSql = whereClausePredicatePrefix + "( (DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID and " + crit.buildWhere() + " )";  | 
  |  1489 |     | 
     | 
  |  1490 |    0 |                Set<String> viewerGroupIds = new TreeSet<String>();  | 
  |  1491 |     | 
     | 
  |  1492 |    0 |                if(principalList != null && !principalList.isEmpty()){ | 
  |  1493 |    0 |                    for(String principalId: principalList){ | 
  |  1494 |    0 |                            viewerGroupIds.addAll(KIMServiceLocator.getGroupService().getGroupIdsForPrincipal(principalId));  | 
  |  1495 |     | 
                   }  | 
  |  1496 |     | 
               }  | 
  |  1497 |     | 
     | 
  |  1498 |     | 
                 | 
  |  1499 |     | 
     | 
  |  1500 |     | 
                 | 
  |  1501 |    0 |                if (viewerGroupIds != null && !viewerGroupIds.isEmpty()) { | 
  |  1502 |     | 
     | 
  |  1503 |    0 |                    returnSql += " or ( " +  | 
  |  1504 |     | 
                       "DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID " +  | 
  |  1505 |     | 
                       "and KREW_ACTN_RQST_T.GRP_ID in ("; | 
  |  1506 |     | 
     | 
  |  1507 |    0 |                    boolean first = true;  | 
  |  1508 |    0 |                    for(String groupId: viewerGroupIds){ | 
  |  1509 |    0 |                        if(!first){ | 
  |  1510 |    0 |                            returnSql += ",";  | 
  |  1511 |     | 
                       }  | 
  |  1512 |    0 |                        returnSql += "'" + groupId + "'";  | 
  |  1513 |    0 |                        first = false;  | 
  |  1514 |     | 
                   }  | 
  |  1515 |    0 |                    returnSql += "))";  | 
  |  1516 |     | 
               }  | 
  |  1517 |    0 |                returnSql += ")";  | 
  |  1518 |     | 
           }  | 
  |  1519 |    0 |            return returnSql;  | 
  |  1520 |     | 
       }  | 
  |  1521 |     | 
     | 
  |  1522 |     | 
       public String getWorkgroupViewerSql(String id, String workgroupName, String whereClausePredicatePrefix) { | 
  |  1523 |    0 |            String sql = "";  | 
  |  1524 |    0 |            if (!org.apache.commons.lang.StringUtils.isEmpty(workgroupName)) { | 
  |  1525 |    0 |                Group group = KIMServiceLocator.getIdentityManagementService().getGroup(id);  | 
  |  1526 |    0 |                sql = whereClausePredicatePrefix + " DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID and KREW_ACTN_RQST_T.GRP_ID = " + group.getGroupId();  | 
  |  1527 |     | 
           }  | 
  |  1528 |    0 |            return sql;  | 
  |  1529 |     | 
       }  | 
  |  1530 |     | 
     | 
  |  1531 |     | 
       public String getApproverSql(String approver, String whereClausePredicatePrefix) { | 
  |  1532 |    0 |            String returnSql = "";  | 
  |  1533 |    0 |            if ((approver != null) && (!"".equals(approver.trim()))) { | 
  |  1534 |    0 |                Map<String, String> m = new HashMap<String, String>();  | 
  |  1535 |    0 |                m.put("principalName", approver); | 
  |  1536 |     | 
     | 
  |  1537 |     | 
                 | 
  |  1538 |    0 |                List<Person> pList = KIMServiceLocator.getPersonService().findPeople(m, false);  | 
  |  1539 |     | 
     | 
  |  1540 |    0 |                if(pList == null || pList.isEmpty() ){ | 
  |  1541 |    0 |                     return "";  | 
  |  1542 |     | 
               }  | 
  |  1543 |     | 
     | 
  |  1544 |    0 |                List<String> principalList = new ArrayList<String>();  | 
  |  1545 |     | 
     | 
  |  1546 |    0 |                for(Person p: pList){ | 
  |  1547 |    0 |                    principalList.add(p.getPrincipalId());  | 
  |  1548 |     | 
               }  | 
  |  1549 |     | 
     | 
  |  1550 |    0 |                Criteria crit = new Criteria("KREW_ACTN_TKN_T", "KREW_ACTN_TKN_T"); | 
  |  1551 |    0 |                crit.in("PRNCPL_ID", principalList, String.class); | 
  |  1552 |     | 
     | 
  |  1553 |    0 |                returnSql = whereClausePredicatePrefix +  | 
  |  1554 |     | 
               " DOC_HDR.DOC_HDR_ID = KREW_ACTN_TKN_T.DOC_HDR_ID and upper(KREW_ACTN_TKN_T.ACTN_CD) in ('" + | 
  |  1555 |     | 
               KEWConstants.ACTION_TAKEN_APPROVED_CD + "','" + KEWConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + "')" +  | 
  |  1556 |     | 
               " and " + crit.buildWhere();  | 
  |  1557 |     | 
           }  | 
  |  1558 |    0 |            return returnSql;  | 
  |  1559 |     | 
       }  | 
  |  1560 |     | 
     | 
  |  1561 |     | 
       public String getDocTypeFullNameWhereSql(String docTypeFullName, String whereClausePredicatePrefix) { | 
  |  1562 |    0 |            StringBuffer returnSql = new StringBuffer(""); | 
  |  1563 |    0 |            if ((docTypeFullName != null) && (!"".equals(docTypeFullName.trim()))) { | 
  |  1564 |     | 
                 | 
  |  1565 |     | 
     | 
  |  1566 |     | 
     | 
  |  1567 |     | 
     | 
  |  1568 |     | 
     | 
  |  1569 |     | 
     | 
  |  1570 |     | 
     | 
  |  1571 |     | 
     | 
  |  1572 |     | 
     | 
  |  1573 |    0 |                DocumentTypeService docSrv = (DocumentTypeService) KEWServiceLocator.getDocumentTypeService();  | 
  |  1574 |    0 |                DocumentType docType = docSrv.findByName(docTypeFullName.trim());  | 
  |  1575 |    0 |                if (docType != null) { | 
  |  1576 |    0 |                    returnSql.append(whereClausePredicatePrefix).append("("); | 
  |  1577 |    0 |                    addDocumentTypeNameToSearchOn(returnSql,docType.getName(), "");  | 
  |  1578 |    0 |                    if (docType.getChildrenDocTypes() != null) { | 
  |  1579 |    0 |                        addChildDocumentTypes(returnSql, docType.getChildrenDocTypes());  | 
  |  1580 |     | 
                   }  | 
  |  1581 |    0 |                    addExtraDocumentTypesToSearch(returnSql,docType);  | 
  |  1582 |    0 |                    returnSql.append(")"); | 
  |  1583 |     | 
               }else{ | 
  |  1584 |    0 |                    returnSql.append(whereClausePredicatePrefix).append("("); | 
  |  1585 |    0 |                    addDocumentTypeLikeNameToSearchOn(returnSql,docTypeFullName.trim(), "");  | 
  |  1586 |    0 |                    returnSql.append(")"); | 
  |  1587 |     | 
               }  | 
  |  1588 |     | 
           }  | 
  |  1589 |    0 |            return returnSql.toString();  | 
  |  1590 |     | 
       }  | 
  |  1591 |     | 
     | 
  |  1592 |     | 
       public void addChildDocumentTypes(StringBuffer whereSql, Collection<DocumentType> childDocumentTypes) { | 
  |  1593 |    0 |            for (DocumentType child : childDocumentTypes) { | 
  |  1594 |    0 |                addDocumentTypeNameToSearchOn(whereSql, child.getName());  | 
  |  1595 |    0 |                addChildDocumentTypes(whereSql, child.getChildrenDocTypes());  | 
  |  1596 |     | 
           }  | 
  |  1597 |    0 |        }  | 
  |  1598 |     | 
     | 
  |  1599 |    0 |        public void addExtraDocumentTypesToSearch(StringBuffer whereSql,DocumentType docType) {} | 
  |  1600 |     | 
     | 
  |  1601 |     | 
       public void addDocumentTypeNameToSearchOn(StringBuffer whereSql,String documentTypeName) { | 
  |  1602 |    0 |            this.addDocumentTypeNameToSearchOn(whereSql, documentTypeName, " or ");  | 
  |  1603 |    0 |        }  | 
  |  1604 |     | 
     | 
  |  1605 |     | 
       public void addDocumentTypeNameToSearchOn(StringBuffer whereSql,String documentTypeName, String clause) { | 
  |  1606 |    0 |            whereSql.append(clause).append(" DOC1.DOC_TYP_NM = '" + documentTypeName + "'"); | 
  |  1607 |    0 |        }  | 
  |  1608 |     | 
       public void addDocumentTypeLikeNameToSearchOn(StringBuffer whereSql,String documentTypeName, String clause) { | 
  |  1609 |    0 |            documentTypeName = documentTypeName.replace('*', '%'); | 
  |  1610 |    0 |            whereSql.append(clause).append(" DOC1.DOC_TYP_NM LIKE '" + documentTypeName + "'"); | 
  |  1611 |    0 |        }  | 
  |  1612 |     | 
     | 
  |  1613 |     | 
       public String getDocRouteNodeSql(String documentTypeFullName, String docRouteLevel, String docRouteLevelLogic, String whereClausePredicatePrefix) { | 
  |  1614 |     | 
             | 
  |  1615 |     | 
             | 
  |  1616 |    0 |            String returnSql = "";  | 
  |  1617 |    0 |            if ((docRouteLevel != null) && (!"".equals(docRouteLevel.trim())) && (!docRouteLevel.equals("-1"))) { | 
  |  1618 |     | 
                     | 
  |  1619 |     | 
                 | 
  |  1620 |     | 
     | 
  |  1621 |     | 
     | 
  |  1622 |     | 
     | 
  |  1623 |     | 
     | 
  |  1624 |     | 
     | 
  |  1625 |     | 
     | 
  |  1626 |     | 
                         | 
  |  1627 |    0 |                    String searchCriteriaRouteNodeName = "";  | 
  |  1628 |     | 
                   try { | 
  |  1629 |    0 |                            long docRouteLevelLong = Long.parseLong(docRouteLevel);  | 
  |  1630 |    0 |                            RouteNode searchCriteriaRouteNode = KEWServiceLocator.getRouteNodeService().findRouteNodeById(docRouteLevelLong);  | 
  |  1631 |     | 
                             | 
  |  1632 |    0 |                            if (searchCriteriaRouteNode != null) { | 
  |  1633 |    0 |                                    searchCriteriaRouteNodeName = searchCriteriaRouteNode.getRouteNodeName();  | 
  |  1634 |     | 
                           }  | 
  |  1635 |    0 |                    } catch (java.lang.NumberFormatException e) { | 
  |  1636 |    0 |                            searchCriteriaRouteNodeName = docRouteLevel;  | 
  |  1637 |    0 |                    }  | 
  |  1638 |     | 
                                         | 
  |  1639 |    0 |                StringBuffer routeNodeCriteria = new StringBuffer("and " + ROUTE_NODE_TABLE + ".NM "); | 
  |  1640 |    0 |                if (KEWConstants.DOC_SEARCH_ROUTE_STATUS_QUALIFIER_EXACT.equalsIgnoreCase(docRouteLevelLogic.trim())) { | 
  |  1641 |    0 |                            routeNodeCriteria.append("= '" + getDbPlatform().escapeString(searchCriteriaRouteNodeName) + "' "); | 
  |  1642 |     | 
               } else { | 
  |  1643 |    0 |                    routeNodeCriteria.append("in ("); | 
  |  1644 |     | 
                     | 
  |  1645 |    0 |                    StringBuffer routeNodeInCriteria = new StringBuffer();  | 
  |  1646 |    0 |                    boolean foundSpecifiedNode = false;  | 
  |  1647 |    0 |                    List<RouteNode> routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(getValidDocumentType(documentTypeFullName), true);  | 
  |  1648 |    0 |                    for (RouteNode routeNode : routeNodes) { | 
  |  1649 |    0 |                        if (searchCriteriaRouteNodeName.equals(routeNode.getRouteNodeName())) { | 
  |  1650 |     | 
                   | 
  |  1651 |     | 
     | 
  |  1652 |     | 
     | 
  |  1653 |     | 
                             | 
  |  1654 |    0 |                            foundSpecifiedNode = true;  | 
  |  1655 |    0 |                            continue;  | 
  |  1656 |     | 
                       }  | 
  |  1657 |     | 
                         | 
  |  1658 |     | 
                         | 
  |  1659 |     | 
                         | 
  |  1660 |    0 |                        if ( (!foundSpecifiedNode && (KEWConstants.DOC_SEARCH_ROUTE_STATUS_QUALIFIER_BEFORE.equalsIgnoreCase(docRouteLevelLogic.trim()))) ||  | 
  |  1661 |     | 
                            (foundSpecifiedNode && (KEWConstants.DOC_SEARCH_ROUTE_STATUS_QUALIFIER_AFTER.equalsIgnoreCase(docRouteLevelLogic.trim()))) ) { | 
  |  1662 |    0 |                            if (routeNodeInCriteria.length() > 0) { | 
  |  1663 |    0 |                                routeNodeInCriteria.append(", "); | 
  |  1664 |     | 
                           }  | 
  |  1665 |    0 |                            routeNodeInCriteria.append("'" + routeNode.getRouteNodeName() + "'"); | 
  |  1666 |     | 
                       }  | 
  |  1667 |     | 
                   }  | 
  |  1668 |    0 |                    if (routeNodeInCriteria.length() > 0) { | 
  |  1669 |    0 |                        routeNodeCriteria.append(routeNodeInCriteria);  | 
  |  1670 |     | 
                   } else { | 
  |  1671 |    0 |                        routeNodeCriteria.append("''"); | 
  |  1672 |     | 
                   }  | 
  |  1673 |    0 |                    routeNodeCriteria.append(") "); | 
  |  1674 |     | 
               }  | 
  |  1675 |    0 |                returnSql = whereClausePredicatePrefix + "DOC_HDR.DOC_HDR_ID = " + ROUTE_NODE_INST_TABLE + ".DOC_HDR_ID and " + ROUTE_NODE_INST_TABLE + ".RTE_NODE_ID = " + ROUTE_NODE_TABLE + ".RTE_NODE_ID and " + ROUTE_NODE_INST_TABLE + ".ACTV_IND = 1 " + routeNodeCriteria.toString() + " ";  | 
  |  1676 |     | 
           }  | 
  |  1677 |    0 |            return returnSql;  | 
  |  1678 |     | 
       }  | 
  |  1679 |     | 
     | 
  |  1680 |     | 
       public String getDocRouteStatusSql(String docRouteStatuses, String whereClausePredicatePrefix) { | 
  |  1681 |    0 |            if ((docRouteStatuses == null) || "".equals(docRouteStatuses.trim())) { | 
  |  1682 |    0 |                return whereClausePredicatePrefix + "DOC_HDR.DOC_HDR_STAT_CD != '" + KEWConstants.ROUTE_HEADER_INITIATED_CD + "'";  | 
  |  1683 |     | 
           } else { | 
  |  1684 |     | 
     | 
  |  1685 |     | 
                 | 
  |  1686 |    0 |                List<String> docRouteStatusList = Arrays.asList(docRouteStatuses.split(",")); | 
  |  1687 |    0 |                String inList = "";  | 
  |  1688 |     | 
     | 
  |  1689 |    0 |                for(String docRouteStatus : docRouteStatusList){ | 
  |  1690 |    0 |                    if(KEWConstants.DOCUMENT_STATUS_PARENT_TYPES.containsKey(docRouteStatus)){ | 
  |  1691 |     | 
                         | 
  |  1692 |    0 |                        for(String docStatusCd : KEWConstants.DOCUMENT_STATUS_PARENT_TYPES.get(docRouteStatus)){ | 
  |  1693 |    0 |                            inList += "'" + getDbPlatform().escapeString(docStatusCd.trim()) + "',";  | 
  |  1694 |     | 
                       }  | 
  |  1695 |     | 
                   } else{ | 
  |  1696 |    0 |                        inList += "'" + getDbPlatform().escapeString(docRouteStatus.trim()) + "',";  | 
  |  1697 |     | 
                   }  | 
  |  1698 |     | 
               }  | 
  |  1699 |    0 |                inList = inList.substring(0,inList.length()-1);   | 
  |  1700 |     | 
     | 
  |  1701 |    0 |                return whereClausePredicatePrefix + " DOC_HDR.DOC_HDR_STAT_CD in (" + inList +")"; | 
  |  1702 |     | 
           }  | 
  |  1703 |     | 
       }  | 
  |  1704 |     | 
     | 
  |  1705 |     | 
         | 
  |  1706 |     | 
     | 
  |  1707 |     | 
     | 
  |  1708 |     | 
     | 
  |  1709 |     | 
     | 
  |  1710 |     | 
     | 
  |  1711 |     | 
     | 
  |  1712 |     | 
     | 
  |  1713 |     | 
     | 
  |  1714 |     | 
     | 
  |  1715 |     | 
     | 
  |  1716 |     | 
       public String getAppDocStatusSql(String appDocStatus, String whereClausePredicatePrefix, int statusTransitionWhereClauseLength) { | 
  |  1717 |    0 |            if ((appDocStatus == null) || "".equals(appDocStatus.trim())) { | 
  |  1718 |    0 |                return "";  | 
  |  1719 |     | 
           } else { | 
  |  1720 |    0 |                    if (statusTransitionWhereClauseLength > 0){ | 
  |  1721 |    0 |                            return whereClausePredicatePrefix + " STAT_TRAN.APP_DOC_STAT_TO = '" + getDbPlatform().escapeString(appDocStatus.trim()) + "'";  | 
  |  1722 |     | 
                   }else{ | 
  |  1723 |    0 |                            return whereClausePredicatePrefix + " DOC_HDR.APP_DOC_STAT = '" + getDbPlatform().escapeString(appDocStatus.trim()) + "'";  | 
  |  1724 |     | 
                   }  | 
  |  1725 |     | 
           }  | 
  |  1726 |     | 
       }  | 
  |  1727 |     | 
     | 
  |  1728 |     | 
     | 
  |  1729 |     | 
         | 
  |  1730 |     | 
     | 
  |  1731 |     | 
         | 
  |  1732 |     | 
     | 
  |  1733 |     | 
     | 
  |  1734 |     | 
     | 
  |  1735 |     | 
     | 
  |  1736 |     | 
     | 
  |  1737 |     | 
       public void filterOutNonQueryAttributes() { | 
  |  1738 |    0 |            List<SearchAttributeCriteriaComponent> newAttributes = new ArrayList<SearchAttributeCriteriaComponent>();  | 
  |  1739 |    0 |            for (SearchAttributeCriteriaComponent component : criteria.getSearchableAttributes()) { | 
  |  1740 |    0 |                if (component != null) { | 
  |  1741 |    0 |                    if ( (StringUtils.isNotBlank(component.getValue())) || (!CollectionUtils.isEmpty(component.getValues())) ) { | 
  |  1742 |    0 |                        newAttributes.add(component);  | 
  |  1743 |     | 
                   }  | 
  |  1744 |     | 
               }  | 
  |  1745 |     | 
           }  | 
  |  1746 |    0 |            criteria.setSearchableAttributes(newAttributes);  | 
  |  1747 |    0 |        }  | 
  |  1748 |     | 
     | 
  |  1749 |     | 
       public String getGeneratedPredicatePrefix(int whereClauseSize) { | 
  |  1750 |    0 |            return (whereClauseSize > 0) ? " and " : " where ";  | 
  |  1751 |     | 
       }  | 
  |  1752 |     | 
     | 
  |  1753 |     | 
       public String establishDateString(String fromDate, String toDate, String tableName, String tableAlias, String colName, String whereStatementClause) { | 
  |  1754 |     | 
       | 
  |  1755 |     | 
     | 
  |  1756 |     | 
     | 
  |  1757 |     | 
     | 
  |  1758 |     | 
     | 
  |  1759 |     | 
     | 
  |  1760 |    0 |            String searchVal = "";  | 
  |  1761 |     | 
     | 
  |  1762 |    0 |                if(fromDate != null && !"".equals(fromDate)) { | 
  |  1763 |     | 
                       try {                            | 
  |  1764 |    0 |                                KNSServiceLocator.getDateTimeService().convertToSqlTimestamp(fromDate);  | 
  |  1765 |    0 |                        } catch (Exception exc) { throw new RiceRuntimeException("Invalid date format", exc); } | 
  |  1766 |     | 
               }  | 
  |  1767 |     | 
                 | 
  |  1768 |    0 |            if(toDate != null && !"".equals(toDate)){ | 
  |  1769 |     | 
               try{ | 
  |  1770 |    0 |                    java.sql.Timestamp dt = KNSServiceLocator.getDateTimeService().convertToSqlTimestamp(toDate);  | 
  |  1771 |    0 |                    SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss"); | 
  |  1772 |     | 
     | 
  |  1773 |    0 |                    if("00:00:00".equals(sdfTime.format(dt))){ | 
  |  1774 |    0 |                        toDate += " 23:59:59";  | 
  |  1775 |     | 
                   }  | 
  |  1776 |     | 
               }  | 
  |  1777 |    0 |                catch (Exception exc) { throw new RiceRuntimeException("Invalid date format", exc); } | 
  |  1778 |     | 
           }  | 
  |  1779 |     | 
     | 
  |  1780 |     | 
     | 
  |  1781 |    0 |            if(fromDate != null && toDate != null && !"".equals(fromDate) && !"".equals(toDate)){ | 
  |  1782 |    0 |                searchVal = fromDate + " .. " + toDate;  | 
  |  1783 |     | 
           }else{ | 
  |  1784 |    0 |                if(fromDate != null && !"".equals(fromDate)){ | 
  |  1785 |    0 |                    searchVal = ">= " + fromDate;  | 
  |  1786 |    0 |                }else if(toDate != null && !"".equals(toDate)){ | 
  |  1787 |    0 |                    searchVal = "<= " + toDate;  | 
  |  1788 |     | 
               } else { | 
  |  1789 |    0 |                                    searchVal =  "";  | 
  |  1790 |     | 
                           }  | 
  |  1791 |     | 
           }  | 
  |  1792 |     | 
     | 
  |  1793 |    0 |            if(searchVal == null || "".equals(searchVal)) { | 
  |  1794 |    0 |                            return "";  | 
  |  1795 |     | 
                   }  | 
  |  1796 |     | 
     | 
  |  1797 |    0 |            Criteria crit = getSqlBuilder().createCriteria(colName, searchVal, tableName, tableAlias, java.sql.Date.class, true, true);  | 
  |  1798 |    0 |            return new StringBuffer(whereStatementClause + crit.buildWhere()).toString();  | 
  |  1799 |     | 
     | 
  |  1800 |     | 
     | 
  |  1801 |     | 
     | 
  |  1802 |     | 
     | 
  |  1803 |     | 
     | 
  |  1804 |     | 
     | 
  |  1805 |     | 
     | 
  |  1806 |     | 
     | 
  |  1807 |     | 
     | 
  |  1808 |     | 
     | 
  |  1809 |     | 
     | 
  |  1810 |     | 
     | 
  |  1811 |     | 
     | 
  |  1812 |     | 
     | 
  |  1813 |     | 
     | 
  |  1814 |     | 
     | 
  |  1815 |     | 
     | 
  |  1816 |     | 
     | 
  |  1817 |     | 
       }  | 
  |  1818 |     | 
     | 
  |  1819 |     | 
       public int getDocumentSearchResultSetLimit() { | 
  |  1820 |    0 |            return DEFAULT_SEARCH_RESULT_CAP;  | 
  |  1821 |     | 
       }  | 
  |  1822 |     | 
     | 
  |  1823 |     | 
       public boolean isProcessResultSet(){ | 
  |  1824 |    0 |            return this.isProcessResultSet;  | 
  |  1825 |     | 
       }  | 
  |  1826 |     | 
       public void setProcessResultSet(boolean isProcessResultSet){ | 
  |  1827 |    0 |            this.isProcessResultSet = isProcessResultSet;  | 
  |  1828 |    0 |        }  | 
  |  1829 |     | 
     | 
  |  1830 |     | 
       public DatabasePlatform getDbPlatform() { | 
  |  1831 |    0 |            if (dbPlatform == null) { | 
  |  1832 |    0 |                dbPlatform = (DatabasePlatform) GlobalResourceLoader.getService(RiceConstants.DB_PLATFORM);  | 
  |  1833 |     | 
           }  | 
  |  1834 |    0 |            return dbPlatform;  | 
  |  1835 |     | 
       }  | 
  |  1836 |     | 
     | 
  |  1837 |     | 
       public MessageMap getMessageMap(DocSearchCriteriaDTO searchCriteria) { | 
  |  1838 |    0 |            setCriteria(searchCriteria);  | 
  |  1839 |    0 |            return this.messageMap;  | 
  |  1840 |     | 
       }  | 
  |  1841 |     | 
     | 
  |  1842 |     | 
       private List<String> tokenizeCriteria(String input){ | 
  |  1843 |    0 |            List<String> lRet = null;  | 
  |  1844 |     | 
     | 
  |  1845 |    0 |            lRet = Arrays.asList(input.split("\\|")); | 
  |  1846 |     | 
     | 
  |  1847 |    0 |            return lRet;  | 
  |  1848 |     | 
       }  | 
  |  1849 |     | 
       private boolean validateNumber(List<String> integers) { | 
  |  1850 |    0 |            for(String integer: integers){ | 
  |  1851 |     | 
             | 
  |  1852 |     | 
             | 
  |  1853 |     | 
             | 
  |  1854 |     | 
           }  | 
  |  1855 |    0 |            return true;  | 
  |  1856 |     | 
       }  | 
  |  1857 |     | 
     | 
  |  1858 |     | 
         | 
  |  1859 |     | 
     | 
  |  1860 |     | 
     | 
  |  1861 |     | 
       public SqlBuilder getSqlBuilder() { | 
  |  1862 |    0 |            if(sqlBuilder == null){ | 
  |  1863 |    0 |                sqlBuilder = new SqlBuilder();  | 
  |  1864 |    0 |                sqlBuilder.setDbPlatform(getDbPlatform());  | 
  |  1865 |    0 |                sqlBuilder.setDateTimeService(KNSServiceLocator.getDateTimeService());  | 
  |  1866 |     | 
           }  | 
  |  1867 |    0 |            return this.sqlBuilder;  | 
  |  1868 |     | 
       }  | 
  |  1869 |     | 
     | 
  |  1870 |     | 
         | 
  |  1871 |     | 
     | 
  |  1872 |     | 
     | 
  |  1873 |     | 
       public void setSqlBuilder(SqlBuilder sqlBuilder) { | 
  |  1874 |    0 |            this.sqlBuilder = sqlBuilder;  | 
  |  1875 |    0 |        }  | 
  |  1876 |     | 
         | 
  |  1877 |     | 
         | 
  |  1878 |     | 
     | 
  |  1879 |     | 
     | 
  |  1880 |     | 
     | 
  |  1881 |     | 
     | 
  |  1882 |     | 
     | 
  |  1883 |     | 
       protected boolean isUsingAtLeastOneSearchAttribute() { | 
  |  1884 |    0 |            return ( (criteria.getSearchableAttributes() != null && criteria.getSearchableAttributes().size() > 0) ||  | 
  |  1885 |     | 
                   StringUtils.isNotBlank(criteria.getDocTypeFullName()) );  | 
  |  1886 |     | 
       }  | 
  |  1887 |     | 
     | 
  |  1888 |     | 
   }  |