1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.impl.document.search;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.joda.time.DateTime;
21 import org.kuali.rice.core.api.CoreApiServiceLocator;
22 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
23 import org.kuali.rice.core.api.uif.RemotableAttributeError;
24 import org.kuali.rice.core.api.uif.RemotableAttributeField;
25 import org.kuali.rice.core.api.util.RiceConstants;
26 import org.kuali.rice.core.framework.persistence.jdbc.sql.Criteria;
27 import org.kuali.rice.core.framework.persistence.jdbc.sql.SqlBuilder;
28 import org.kuali.rice.core.framework.persistence.platform.DatabasePlatform;
29 import org.kuali.rice.kew.api.KewApiConstants;
30 import org.kuali.rice.kew.api.KewApiServiceLocator;
31 import org.kuali.rice.kew.api.document.Document;
32 import org.kuali.rice.kew.api.document.DocumentStatus;
33 import org.kuali.rice.kew.api.document.DocumentStatusCategory;
34 import org.kuali.rice.kew.api.document.attribute.DocumentAttribute;
35 import org.kuali.rice.kew.api.document.attribute.DocumentAttributeFactory;
36 import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
37 import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
38 import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
39 import org.kuali.rice.kew.api.document.search.RouteNodeLookupLogic;
40 import org.kuali.rice.kew.docsearch.DocumentSearchInternalUtils;
41 import org.kuali.rice.kew.docsearch.QueryComponent;
42 import org.kuali.rice.kew.docsearch.SearchableAttributeValue;
43 import org.kuali.rice.kew.doctype.bo.DocumentType;
44 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
45 import org.kuali.rice.kew.engine.node.RouteNode;
46 import org.kuali.rice.kew.service.KEWServiceLocator;
47 import org.kuali.rice.kew.util.PerformanceLogger;
48 import org.kuali.rice.kim.api.identity.Person;
49 import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
50 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
51 import org.kuali.rice.krad.util.KRADConstants;
52 import org.kuali.rice.krad.util.MessageMap;
53
54 import java.sql.ResultSet;
55 import java.sql.SQLException;
56 import java.sql.Statement;
57 import java.sql.Timestamp;
58 import java.util.ArrayList;
59 import java.util.Collection;
60 import java.util.Collections;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Set;
66 import java.util.TreeSet;
67
68
69
70
71
72
73
74 public class DocumentSearchGeneratorImpl implements DocumentSearchGenerator {
75
76 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentSearchGeneratorImpl.class);
77
78 private static final String ROUTE_NODE_TABLE = "KREW_RTE_NODE_T";
79 private static final String ROUTE_NODE_INST_TABLE = "KREW_RTE_NODE_INSTN_T";
80 private static final String DATABASE_WILDCARD_CHARACTER_STRING = "%";
81 private static final char DATABASE_WILDCARD_CHARACTER = DATABASE_WILDCARD_CHARACTER_STRING.toCharArray()[0];
82
83 private DatabasePlatform dbPlatform;
84 private MessageMap messageMap;
85
86 private SqlBuilder sqlBuilder = null;
87
88 @Override
89 public DocumentSearchCriteria clearSearch(DocumentSearchCriteria criteria) {
90 return DocumentSearchCriteria.Builder.create().build();
91 }
92
93 public DocumentType getValidDocumentType(String documentTypeFullName) {
94 if (!org.apache.commons.lang.StringUtils.isEmpty(documentTypeFullName)) {
95 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByNameCaseInsensitive(documentTypeFullName);
96 if (documentType == null) {
97 throw new RuntimeException("No Valid Document Type Found for document type name '" + documentTypeFullName + "'");
98 }
99 return documentType;
100 }
101 return null;
102 }
103
104 @Override
105 public List<RemotableAttributeError> validateSearchableAttributes(DocumentSearchCriteria.Builder criteria) {
106 List<RemotableAttributeError> errors = new ArrayList<RemotableAttributeError>();
107 DocumentType documentType = null;
108 try{
109 documentType = getValidDocumentType(criteria.getDocumentTypeName());
110 }catch(RuntimeException re){
111 errors.add(RemotableAttributeError.Builder.create("documentTypeName", re.getMessage()).build());
112 }
113
114 if (documentType != null) {
115 errors = KEWServiceLocator.getDocumentSearchCustomizationMediator().validateLookupFieldParameters(documentType, criteria.build());
116 } else {
117 criteria.setDocumentAttributeValues(new HashMap<String, List<String>>());
118 }
119 return errors == null ? Collections.<RemotableAttributeError>emptyList() : Collections.unmodifiableList(errors);
120 }
121
122 public QueryComponent getSearchableAttributeSql(Map<String, List<String>> documentAttributeValues, List<RemotableAttributeField> searchFields, String whereClausePredicatePrefix) {
123
124 StringBuilder fromSql = new StringBuilder();
125 StringBuilder whereSql = new StringBuilder();
126
127
128 Criteria finalCriteria = null;
129 int tableIndex = 1;
130 SqlBuilder sqlBuilder = this.getSqlBuilder();
131
132 for (String documentAttributeName : documentAttributeValues.keySet()) {
133 String documentAttributeNameForSQL = documentAttributeName;
134 if (documentAttributeName.contains(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX)) {
135 documentAttributeNameForSQL = documentAttributeName.replaceFirst(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX, "");
136 }
137 List<String> searchValues = documentAttributeValues.get(documentAttributeName);
138 if (CollectionUtils.isEmpty(searchValues) || documentAttributeName.contains(KRADConstants.CHECKBOX_PRESENT_ON_FORM_ANNOTATION)) {
139 continue;
140 }
141
142 String tableAlias = "EXT" + tableIndex;
143 RemotableAttributeField searchField = getSearchFieldByName(documentAttributeName, searchFields);
144 String tableName = DocumentSearchInternalUtils.getAttributeTableName(searchField);
145 boolean caseSensitive = DocumentSearchInternalUtils.isLookupCaseSensitive(searchField);
146
147 Criteria crit = null;
148
149 Class<?> dataTypeClass = DocumentSearchInternalUtils.getDataTypeClass(searchField);
150 if (searchValues.size() > 1) {
151
152 crit = new Criteria(tableName, tableAlias);
153 crit.setDbPlatform(sqlBuilder.getDbPlatform());
154 crit.in("VAL", searchValues, dataTypeClass);
155 } else {
156 crit = sqlBuilder.createCriteria("VAL", searchValues.get(0) , tableName, tableAlias, dataTypeClass, !caseSensitive);
157 }
158
159 sqlBuilder.addCriteria("KEY_CD", documentAttributeNameForSQL, String.class, false, false, crit);
160 sqlBuilder.andCriteria("DOC_HDR_ID", tableAlias + ".DOC_HDR_ID", "KREW_DOC_HDR_T", "DOC_HDR", SqlBuilder.JoinType.class, false, false, crit);
161
162 if (finalCriteria == null ){
163 finalCriteria = crit;
164 } else{
165 sqlBuilder.andCriteria(finalCriteria, crit);
166 }
167
168
169
170 String whereClausePrefix = (whereSql.length() == 0) ? whereClausePredicatePrefix : getGeneratedPredicatePrefix(whereSql.length());
171 QueryComponent qc = generateSearchableAttributeSql(tableName, documentAttributeNameForSQL, whereClausePrefix, tableIndex);
172 fromSql.append(qc.getFromSql());
173 tableIndex++;
174 }
175
176 if (finalCriteria == null) {
177 return new QueryComponent("", "", "");
178 }
179
180 String whereClausePrefix = (whereSql.length() == 0) ? whereClausePredicatePrefix : getGeneratedPredicatePrefix(whereSql.length());
181
182 return new QueryComponent("", fromSql.toString(), whereClausePrefix + " " + finalCriteria.buildWhere());
183 }
184
185 private RemotableAttributeField getSearchFieldByName(String fieldName, List<RemotableAttributeField> searchFields) {
186 for (RemotableAttributeField searchField : searchFields) {
187 if (searchField.getName().equals(fieldName)
188 || searchField.getName().equals(KewApiConstants.DOCUMENT_ATTRIBUTE_FIELD_PREFIX + fieldName)) {
189 return searchField;
190 }
191 }
192 throw new IllegalStateException("Failed to locate a RemotableAttributeField for fieldName=" + fieldName);
193 }
194
195 public QueryComponent generateSearchableAttributeSql(String tableName, String documentAttributeName, String whereSqlStarter,int tableIndex) {
196 String tableIdentifier = "EXT" + tableIndex;
197 QueryComponent joinSqlComponent = getSearchableAttributeJoinSql(tableName, tableIdentifier, whereSqlStarter, documentAttributeName);
198 return new QueryComponent("", joinSqlComponent.getFromSql(), joinSqlComponent.getWhereSql());
199 }
200
201 public QueryComponent getSearchableAttributeJoinSql(String tableName, String tableIdentifier, String whereSqlStarter, String attributeTableKeyColumnName) {
202 return new QueryComponent("", generateSearchableAttributeFromSql(tableName, tableIdentifier).toString(), generateSearchableAttributeWhereClauseJoin(whereSqlStarter, tableIdentifier, attributeTableKeyColumnName).toString());
203 }
204
205 public StringBuilder generateSearchableAttributeWhereClauseJoin(String whereSqlStarter,String tableIdentifier,String attributeTableKeyColumnName) {
206 StringBuilder whereSql = new StringBuilder(constructWhereClauseElement(whereSqlStarter, "DOC_HDR.DOC_HDR_ID", "=", getDbPlatform().escapeString(tableIdentifier + ".DOC_HDR_ID"), null, null));
207 whereSql.append(constructWhereClauseElement(" and ", tableIdentifier + ".KEY_CD", "=",
208 getDbPlatform().escapeString(attributeTableKeyColumnName), "'", "'"));
209 return whereSql;
210 }
211
212 public StringBuilder generateSearchableAttributeFromSql(String tableName, String tableIdentifier) {
213 if (StringUtils.isBlank(tableName)) {
214 throw new IllegalArgumentException("tableName was null or blank");
215 }
216 if (StringUtils.isBlank(tableIdentifier)) {
217 throw new IllegalArgumentException("tableIdentifier was null or blank");
218 }
219 StringBuilder fromSql = new StringBuilder();
220 fromSql.append(" ,").append(tableName).append(" ").append(getDbPlatform().escapeString(tableIdentifier)).append(" ");
221 return fromSql;
222 }
223
224 public StringBuilder constructWhereClauseElement(String clauseStarter,String queryTableColumnName,String operand,String valueToSearch,String valuePrefix,String valueSuffix) {
225 StringBuilder whereSql = new StringBuilder();
226 valuePrefix = (valuePrefix != null) ? valuePrefix : "";
227 valueSuffix = (valueSuffix != null) ? valueSuffix : "";
228 whereSql.append(" " + clauseStarter + " ").append(getDbPlatform().escapeString(queryTableColumnName)).append(" " + operand + " ").append(valuePrefix).append(valueToSearch).append(valueSuffix).append(" ");
229 return whereSql;
230 }
231
232 @Override
233 public DocumentSearchResults.Builder processResultSet(DocumentSearchCriteria criteria, boolean criteriaModified, Statement searchAttributeStatement, ResultSet resultSet, int maxResultCap, int fetchLimit) throws SQLException {
234 DocumentSearchCriteria.Builder criteriaBuilder = DocumentSearchCriteria.Builder.create(criteria);
235 DocumentSearchResults.Builder results = DocumentSearchResults.Builder.create(criteriaBuilder);
236 results.setCriteriaModified(criteriaModified);
237 int size = 0;
238 List<DocumentSearchResult.Builder> resultList = new ArrayList<DocumentSearchResult.Builder>();
239 results.setSearchResults(resultList);
240 Map<String, DocumentSearchResult.Builder> resultMap = new HashMap<String, DocumentSearchResult.Builder>();
241 PerformanceLogger perfLog = new PerformanceLogger();
242 int iteration = 0;
243 int startAt = (criteria.getStartAtIndex()==null) ? 0 : criteria.getStartAtIndex();
244 maxResultCap += startAt;
245 boolean resultSetHasNext = resultSet.next();
246 while ( resultSetHasNext && resultMap.size() < maxResultCap && iteration++ < fetchLimit && startAt >= 0) {
247
248 if(iteration <= startAt) {
249 resultSetHasNext = resultSet.next();
250 continue;
251 }
252
253 DocumentSearchResult.Builder resultBuilder = processRow(criteria, searchAttributeStatement, resultSet);
254 String documentId = resultBuilder.getDocument().getDocumentId();
255 if (!resultMap.containsKey(documentId)) {
256 resultList.add(resultBuilder);
257 resultMap.put(documentId, resultBuilder);
258 size++;
259 } else {
260
261 DocumentSearchResult.Builder previousEntry = resultMap.get(documentId);
262 handleMultipleDocumentRows(previousEntry, resultBuilder);
263 }
264 resultSetHasNext = resultSet.next();
265 }
266
267 perfLog.log("Time to read doc search results.", true);
268
269 results.setOverThreshold(resultSetHasNext);
270
271 LOG.debug("Processed "+size+" document search result rows.");
272 return results;
273 }
274
275
276
277
278
279
280
281
282 private void handleMultipleDocumentRows(DocumentSearchResult.Builder existingRow, DocumentSearchResult.Builder newRow) {
283 for (DocumentAttribute.AbstractBuilder<?> newDocumentAttribute : newRow.getDocumentAttributes()) {
284 existingRow.getDocumentAttributes().add(newDocumentAttribute);
285 }
286 }
287
288
289
290
291
292
293
294
295
296 protected DocumentSearchResult.Builder processRow(DocumentSearchCriteria criteria, Statement searchAttributeStatement, ResultSet rs) throws SQLException {
297
298 String documentId = rs.getString("DOC_HDR_ID");
299 String initiatorPrincipalId = rs.getString("INITR_PRNCPL_ID");
300 String documentTypeName = rs.getString("DOC_TYP_NM");
301 org.kuali.rice.kew.api.doctype.DocumentType documentType =
302 KewApiServiceLocator.getDocumentTypeService().getDocumentTypeByName(documentTypeName);
303 if (documentType == null) {
304 throw new IllegalStateException("Failed to locate a document type with the given name: " + documentTypeName);
305 }
306 String documentTypeId = documentType.getId();
307
308 Document.Builder documentBuilder = Document.Builder.create(documentId, initiatorPrincipalId, documentTypeName, documentTypeId);
309 DocumentSearchResult.Builder resultBuilder = DocumentSearchResult.Builder.create(documentBuilder);
310
311 String statusCode = rs.getString("DOC_HDR_STAT_CD");
312 Timestamp createTimestamp = rs.getTimestamp("CRTE_DT");
313 String title = rs.getString("TTL");
314 String applicationDocumentStatus = rs.getString("APP_DOC_STAT");
315
316 documentBuilder.setStatus(DocumentStatus.fromCode(statusCode));
317 documentBuilder.setDateCreated(new DateTime(createTimestamp.getTime()));
318 documentBuilder.setTitle(title);
319 documentBuilder.setApplicationDocumentStatus(applicationDocumentStatus);
320 documentBuilder.setApplicationDocumentStatusDate(new DateTime(rs.getTimestamp("APP_DOC_STAT_MDFN_DT")));
321 documentBuilder.setDateApproved(new DateTime(rs.getTimestamp("APRV_DT")));
322 documentBuilder.setDateFinalized(new DateTime(rs.getTimestamp("FNL_DT")));
323 documentBuilder.setApplicationDocumentId(rs.getString("APP_DOC_ID"));
324 documentBuilder.setDateLastModified(new DateTime(rs.getTimestamp("STAT_MDFN_DT")));
325 documentBuilder.setRoutedByPrincipalId(rs.getString("RTE_PRNCPL_ID"));
326
327
328 documentBuilder.setDocumentHandlerUrl(rs.getString("DOC_HDLR_URL"));
329
330 if (isUsingAtLeastOneSearchAttribute(criteria)) {
331 populateDocumentAttributesValues(resultBuilder, searchAttributeStatement);
332 }
333
334 return resultBuilder;
335 }
336
337
338
339
340
341
342
343
344
345 public void populateDocumentAttributesValues(DocumentSearchResult.Builder resultBuilder, Statement searchAttributeStatement) throws SQLException {
346 searchAttributeStatement.setFetchSize(50);
347 String documentId = resultBuilder.getDocument().getDocumentId();
348 List<SearchableAttributeValue> attributeValues = DocumentSearchInternalUtils
349 .getSearchableAttributeValueObjectTypes();
350 PerformanceLogger perfLog = new PerformanceLogger(documentId);
351 for (SearchableAttributeValue searchAttValue : attributeValues) {
352 String attributeSql = "select KEY_CD, VAL from " + searchAttValue.getAttributeTableName() + " where DOC_HDR_ID = '" + documentId + "'";
353 ResultSet attributeResultSet = null;
354 try {
355 attributeResultSet = searchAttributeStatement.executeQuery(attributeSql);
356 while (attributeResultSet.next()) {
357 searchAttValue.setSearchableAttributeKey(attributeResultSet.getString("KEY_CD"));
358 searchAttValue.setupAttributeValue(attributeResultSet, "VAL");
359 if ( (!org.apache.commons.lang.StringUtils.isEmpty(searchAttValue.getSearchableAttributeKey())) && (searchAttValue.getSearchableAttributeValue() != null) ) {
360 DocumentAttribute documentAttribute = searchAttValue.toDocumentAttribute();
361 resultBuilder.getDocumentAttributes().add(DocumentAttributeFactory.loadContractIntoBuilder(
362 documentAttribute));
363 }
364 }
365 } finally {
366 if (attributeResultSet != null) {
367 try {
368 attributeResultSet.close();
369 } catch (Exception e) {
370 LOG.warn("Could not close searchable attribute result set for class " + searchAttValue.getClass().getName(),e);
371 }
372 }
373 }
374 }
375 perfLog.log("Time to execute doc search search attribute queries.", true);
376 }
377
378 @SuppressWarnings("deprecation")
379 public String generateSearchSql(DocumentSearchCriteria criteria, List<RemotableAttributeField> searchFields) {
380
381 String docTypeTableAlias = "DOC1";
382 String docHeaderTableAlias = "DOC_HDR";
383
384 String sqlPrefix = "Select * from (";
385 String sqlSuffix = ") FINAL_SEARCH order by FINAL_SEARCH.CRTE_DT desc";
386
387
388 StringBuilder selectSQL = new StringBuilder("select DISTINCT("+ docHeaderTableAlias +".DOC_HDR_ID), "
389 + StringUtils.join(new String[] {
390 docHeaderTableAlias + ".INITR_PRNCPL_ID",
391 docHeaderTableAlias + ".DOC_HDR_STAT_CD",
392 docHeaderTableAlias + ".CRTE_DT",
393 docHeaderTableAlias + ".TTL",
394 docHeaderTableAlias + ".APP_DOC_STAT",
395 docHeaderTableAlias + ".STAT_MDFN_DT",
396 docHeaderTableAlias + ".APRV_DT",
397 docHeaderTableAlias + ".FNL_DT",
398 docHeaderTableAlias + ".APP_DOC_ID",
399 docHeaderTableAlias + ".RTE_PRNCPL_ID",
400 docHeaderTableAlias + ".APP_DOC_STAT_MDFN_DT",
401 docTypeTableAlias + ".DOC_TYP_NM",
402 docTypeTableAlias + ".LBL",
403 docTypeTableAlias + ".DOC_HDLR_URL",
404 docTypeTableAlias + ".ACTV_IND"
405 }, ", "));
406 StringBuilder fromSQL = new StringBuilder(" from KREW_DOC_TYP_T "+ docTypeTableAlias +" ");
407 StringBuilder fromSQLForDocHeaderTable = new StringBuilder(", KREW_DOC_HDR_T " + docHeaderTableAlias + " ");
408
409 StringBuilder whereSQL = new StringBuilder();
410 whereSQL.append(getDocumentIdSql(criteria.getDocumentId(), getGeneratedPredicatePrefix(whereSQL.length()), docHeaderTableAlias));
411
412 String principalInitiatorIdSql = getInitiatorIdSql(criteria.getInitiatorPrincipalId(), getGeneratedPredicatePrefix(whereSQL.length()));
413 if (StringUtils.isNotBlank(principalInitiatorIdSql)) {
414 whereSQL.append(principalInitiatorIdSql);
415 } else {
416 whereSQL.append(getInitiatorSql(criteria.getInitiatorPrincipalName(), getGeneratedPredicatePrefix(whereSQL.length())));
417 }
418 whereSQL.append(getAppDocIdSql(criteria.getApplicationDocumentId(), getGeneratedPredicatePrefix(whereSQL.length())));
419 whereSQL.append(getDateCreatedSql(criteria.getDateCreatedFrom(), criteria.getDateCreatedTo(), getGeneratedPredicatePrefix(whereSQL.length())));
420 whereSQL.append(getDateLastModifiedSql(criteria.getDateLastModifiedFrom(), criteria.getDateLastModifiedTo(), getGeneratedPredicatePrefix(whereSQL.length())));
421 whereSQL.append(getDateApprovedSql(criteria.getDateApprovedFrom(), criteria.getDateApprovedTo(), getGeneratedPredicatePrefix(whereSQL.length())));
422 whereSQL.append(getDateFinalizedSql(criteria.getDateFinalizedFrom(), criteria.getDateFinalizedTo(), getGeneratedPredicatePrefix(whereSQL.length())));
423
424
425 String principalViewerSql = getViewerSql(criteria.getViewerPrincipalName(), getGeneratedPredicatePrefix(whereSQL.length()));
426 String principalViewerIdSql = getViewerIdSql(criteria.getViewerPrincipalId(), getGeneratedPredicatePrefix(whereSQL.length()));
427
428 if (StringUtils.isNotBlank(principalViewerIdSql)){
429 principalViewerSql = "";
430 }
431 String groupViewerSql = getGroupViewerSql(criteria.getGroupViewerId(), getGeneratedPredicatePrefix(whereSQL.length()));
432 if (StringUtils.isNotBlank(principalViewerSql) || StringUtils.isNotBlank(groupViewerSql) || StringUtils.isNotBlank(principalViewerIdSql) ) {
433 whereSQL.append(principalViewerSql);
434 whereSQL.append(principalViewerIdSql);
435 whereSQL.append(groupViewerSql);
436 fromSQL.append(", KREW_ACTN_RQST_T ");
437 }
438
439 String principalApproverSql = getApproverSql(criteria.getApproverPrincipalName(), getGeneratedPredicatePrefix(whereSQL.length()));
440 String principalApproverIdSql = getApproverIdSql(criteria.getApproverPrincipalId(), getGeneratedPredicatePrefix(whereSQL.length()));
441
442 if (StringUtils.isNotBlank(principalApproverIdSql)){
443 principalApproverSql = "";
444 }
445 if (StringUtils.isNotBlank(principalApproverSql) || StringUtils.isNotBlank(principalApproverIdSql)) {
446 whereSQL.append(principalApproverSql);
447 whereSQL.append(principalApproverIdSql);
448 fromSQL.append(", KREW_ACTN_TKN_T ");
449 }
450
451
452
453 String docRouteNodeSql = getDocRouteNodeSql(criteria.getDocumentTypeName(), criteria.getRouteNodeName(), criteria.getRouteNodeLookupLogic(), getGeneratedPredicatePrefix(whereSQL.length()));
454 if (StringUtils.isNotBlank(docRouteNodeSql)) {
455 whereSQL.append(docRouteNodeSql);
456 fromSQL.append(", KREW_RTE_NODE_INSTN_T ");
457 fromSQL.append(", KREW_RTE_NODE_T ");
458 }
459
460 if (!criteria.getDocumentAttributeValues().isEmpty()) {
461 QueryComponent queryComponent = getSearchableAttributeSql(criteria.getDocumentAttributeValues(), searchFields, getGeneratedPredicatePrefix(
462 whereSQL.length()));
463 selectSQL.append(queryComponent.getSelectSql());
464 fromSQL.append(queryComponent.getFromSql());
465 whereSQL.append(queryComponent.getWhereSql());
466 }
467
468 whereSQL.append(getDocTypeFullNameWhereSql(criteria, getGeneratedPredicatePrefix(whereSQL.length())));
469 whereSQL.append(getDocTitleSql(criteria.getTitle(), getGeneratedPredicatePrefix(whereSQL.length())));
470 whereSQL.append(getDocumentStatusSql(criteria.getDocumentStatuses(), criteria.getDocumentStatusCategories(), getGeneratedPredicatePrefix(whereSQL.length())));
471 whereSQL.append(getGeneratedPredicatePrefix(whereSQL.length())).append(" DOC_HDR.DOC_TYP_ID = DOC1.DOC_TYP_ID ");
472 fromSQL.append(fromSQLForDocHeaderTable);
473
474
475 String statusTransitionWhereClause = getStatusTransitionDateSql(criteria.getDateApplicationDocumentStatusChangedFrom(), criteria.getDateApplicationDocumentStatusChangedTo(), getGeneratedPredicatePrefix(whereSQL.length()));
476
477 List<String> applicationDocumentStatuses = criteria.getApplicationDocumentStatuses();
478
479 if (!StringUtils.isBlank(criteria.getApplicationDocumentStatus())) {
480 if (!criteria.getApplicationDocumentStatuses().contains(criteria.getApplicationDocumentStatus())) {
481 applicationDocumentStatuses = new ArrayList<String>(criteria.getApplicationDocumentStatuses());
482 applicationDocumentStatuses.add(criteria.getApplicationDocumentStatus());
483 }
484 }
485
486 whereSQL.append(getAppDocStatusesSql(applicationDocumentStatuses, getGeneratedPredicatePrefix(
487 whereSQL.length()), statusTransitionWhereClause.length()));
488 if (statusTransitionWhereClause.length() > 0){
489 whereSQL.append(statusTransitionWhereClause);
490 whereSQL.append(getGeneratedPredicatePrefix(whereSQL.length())).append(" DOC_HDR.DOC_HDR_ID = STAT_TRAN.DOC_HDR_ID ");
491 fromSQL.append(", KREW_APP_DOC_STAT_TRAN_T STAT_TRAN ");
492 }
493
494 String finalizedSql = sqlPrefix + " " + selectSQL.toString() + " " + fromSQL.toString() + " " + whereSQL.toString() + " " + sqlSuffix;
495
496 LOG.info("*********** SEARCH SQL ***************");
497 LOG.info(finalizedSql);
498 LOG.info("**************************************");
499 return finalizedSql;
500 }
501
502 public String getDocumentIdSql(String documentId, String whereClausePredicatePrefix, String tableAlias) {
503 if (StringUtils.isBlank(documentId)) {
504 return "";
505 } else {
506
507
508 Criteria crit = getSqlBuilder().createCriteria("DOC_HDR_ID", documentId, "KREW_DOC_HDR_T", tableAlias, String.class, false, true);
509 return new StringBuilder(whereClausePredicatePrefix + crit.buildWhere()).toString();
510 }
511 }
512
513 public String getDocTitleSql(String docTitle, String whereClausePredicatePrefix) {
514 if (StringUtils.isBlank(docTitle)) {
515 return "";
516 } else {
517
518 docTitle = docTitle.trim().replace("\'", "\'\'");
519 SqlBuilder sqlBuild = new SqlBuilder();
520 Criteria crit = new Criteria("KREW_DOC_HDR_T", "DOC_HDR");
521 sqlBuild.addCriteria("TTL", docTitle, String.class, true, true, crit);
522 return new StringBuilder(whereClausePredicatePrefix + crit.buildWhere()).toString();
523 }
524 }
525
526
527
528 public String getAppDocIdSql(String appDocId, String whereClausePredicatePrefix) {
529 if (StringUtils.isBlank(appDocId)) {
530 return "";
531 } else {
532 String tableAlias = "DOC_HDR";
533 Criteria crit = getSqlBuilder().createCriteria("APP_DOC_ID", appDocId, "KREW_DOC_HDR_T", tableAlias,String.class);
534 return new StringBuilder(whereClausePredicatePrefix + crit.buildWhere()).toString();
535 }
536 }
537
538 public String getDateCreatedSql(DateTime fromDateCreated, DateTime toDateCreated, String whereClausePredicatePrefix) {
539 return establishDateString(fromDateCreated, toDateCreated, "KREW_DOC_HDR_T", "DOC_HDR", "CRTE_DT", whereClausePredicatePrefix);
540 }
541
542 public String getDateApprovedSql(DateTime fromDateApproved, DateTime toDateApproved, String whereClausePredicatePrefix) {
543 return establishDateString(fromDateApproved, toDateApproved, "KREW_DOC_HDR_T", "DOC_HDR", "APRV_DT", whereClausePredicatePrefix);
544 }
545
546 public String getDateFinalizedSql(DateTime fromDateFinalized, DateTime toDateFinalized, String whereClausePredicatePrefix) {
547 return establishDateString(fromDateFinalized, toDateFinalized, "KREW_DOC_HDR_T", "DOC_HDR", "FNL_DT", whereClausePredicatePrefix);
548 }
549
550 public String getDateLastModifiedSql(DateTime fromDateLastModified, DateTime toDateLastModified, String whereClausePredicatePrefix) {
551 return establishDateString(fromDateLastModified, toDateLastModified, "KREW_DOC_HDR_T", "DOC_HDR", "STAT_MDFN_DT", whereClausePredicatePrefix);
552 }
553
554 public String getStatusTransitionDateSql(DateTime fromStatusTransitionDate, DateTime toStatusTransitionDate, String whereClausePredicatePrefix) {
555 return establishDateString(fromStatusTransitionDate, toStatusTransitionDate, "KREW_DOC_HDR_T", "DOC_HDR", "APP_DOC_STAT_MDFN_DT", whereClausePredicatePrefix);
556 }
557
558 public String getViewerSql(String viewer, String whereClausePredicatePrefix) {
559 StringBuilder returnSql = new StringBuilder();
560 if (StringUtils.isNotBlank(viewer)) {
561 Map<String, String> m = new HashMap<String, String>();
562 m.put("principalName", viewer);
563
564
565 List<Person> personList = KimApiServiceLocator.getPersonService().findPeople(m, false);
566 List<String> principalList = new ArrayList<String>();
567
568 if(CollectionUtils.isEmpty(personList)) {
569
570
571 PrincipalContract tempPrincipal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(viewer.trim());
572 if (tempPrincipal != null) {
573 principalList.add(tempPrincipal.getPrincipalId());
574 } else {
575
576
577 return new StringBuilder(whereClausePredicatePrefix + " 1 = 0 ").toString();
578 }
579 }
580
581 for (Person person : personList){
582 principalList.add(person.getPrincipalId());
583 }
584
585 Criteria crit = new Criteria("KREW_ACTN_RQST_T", "KREW_ACTN_RQST_T");
586 crit.in("PRNCPL_ID", principalList, String.class);
587 returnSql.append(whereClausePredicatePrefix + "( (DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID and " + crit.buildWhere() + " )");
588
589 Set<String> viewerGroupIds = new TreeSet<String>();
590
591 if(CollectionUtils.isNotEmpty(principalList)) {
592 for(String principalId: principalList){
593 viewerGroupIds.addAll(KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId));
594 }
595 }
596
597
598
599 if (viewerGroupIds != null && !viewerGroupIds.isEmpty()) {
600
601 returnSql.append(" or ( " +
602 "DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID " +
603 "and KREW_ACTN_RQST_T.GRP_ID in (");
604
605 boolean first = true;
606 for (String groupId : viewerGroupIds){
607 if(!first){
608 returnSql.append(",");
609 }
610 returnSql.append("'").append(groupId).append("'");
611 first = false;
612 }
613 returnSql.append("))");
614 }
615 returnSql.append(")");
616 }
617 return returnSql.toString();
618 }
619
620 public String getViewerIdSql(String viewerId, String whereClausePredicatePrefix) {
621 StringBuilder returnSql = new StringBuilder();
622 if (StringUtils.isNotBlank(viewerId)) {
623 Map<String, String> m = new HashMap<String, String>();
624 m.put("principalId", viewerId);
625
626
627 List<Person> personList = KimApiServiceLocator.getPersonService().findPeople(m, false);
628 List<String> principalList = new ArrayList<String>();
629
630 if(CollectionUtils.isEmpty(personList)) {
631
632 return new StringBuilder(whereClausePredicatePrefix + " 1 = 0 ").toString();
633 }
634
635 for (Person person : personList){
636 principalList.add(person.getPrincipalId());
637 }
638
639 Criteria crit = new Criteria("KREW_ACTN_RQST_T", "KREW_ACTN_RQST_T");
640 crit.in("PRNCPL_ID", principalList, String.class);
641 returnSql.append(whereClausePredicatePrefix + "( DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID and " + crit.buildWhere() + " )");
642 }
643 return returnSql.toString();
644 }
645
646 public String getGroupViewerSql(String groupId, String whereClausePredicatePrefix) {
647 String sql = "";
648 if (StringUtils.isNotBlank(groupId)) {
649 sql = whereClausePredicatePrefix + " DOC_HDR.DOC_HDR_ID = KREW_ACTN_RQST_T.DOC_HDR_ID and KREW_ACTN_RQST_T.GRP_ID = '" + groupId + "'";
650 }
651 return sql;
652 }
653
654 public String getInitiatorSql(String initiatorPrincipalName, String whereClausePredicatePrefix) {
655
656 if (StringUtils.isBlank(initiatorPrincipalName)) {
657 return "";
658 }
659
660 String tableAlias = "DOC_HDR";
661
662 Map<String, String> m = new HashMap<String, String>();
663 m.put("principalName", initiatorPrincipalName);
664
665
666 List<Person> pList = KimApiServiceLocator.getPersonService().findPeople(m, false);
667 List<String> principalList = new ArrayList<String>();
668
669 if(pList == null || pList.isEmpty() ){
670
671
672 PrincipalContract tempPrincipal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(initiatorPrincipalName.trim());
673 if (tempPrincipal != null) {
674 principalList.add(tempPrincipal.getPrincipalId());
675 } else {
676
677 return new StringBuilder(whereClausePredicatePrefix + " 1 = 0 ").toString();
678 }
679 }
680
681 for(Person p: pList){
682 principalList.add(p.getPrincipalId());
683 }
684
685 Criteria crit = new Criteria("KREW_DOC_HDR_T", tableAlias);
686 crit.in("INITR_PRNCPL_ID", principalList, String.class);
687
688 return new StringBuilder(whereClausePredicatePrefix + crit.buildWhere()).toString();
689 }
690
691 public String getInitiatorIdSql(String initiatorPrincipalId, String whereClausePredicatePrefix) {
692
693 if (StringUtils.isBlank(initiatorPrincipalId)) {
694 return "";
695 }
696
697 String tableAlias = "DOC_HDR";
698
699 Map<String, String> m = new HashMap<String, String>();
700 m.put("principalId", initiatorPrincipalId);
701
702
703 List<Person> pList = KimApiServiceLocator.getPersonService().findPeople(m, false);
704 List<String> principalList = new ArrayList<String>();
705
706 if(pList == null || pList.isEmpty() ){
707
708 return new StringBuilder(whereClausePredicatePrefix + " 1 = 0 ").toString();
709 }
710
711 for(Person p: pList){
712 principalList.add(p.getPrincipalId());
713 }
714
715 Criteria crit = new Criteria("KREW_DOC_HDR_T", tableAlias);
716 crit.in("INITR_PRNCPL_ID", principalList, String.class);
717
718 return new StringBuilder(whereClausePredicatePrefix + crit.buildWhere()).toString();
719 }
720
721 public String getApproverSql(String approver, String whereClausePredicatePrefix) {
722 String returnSql = "";
723 if (StringUtils.isNotBlank(approver)) {
724 Map<String, String> m = new HashMap<String, String>();
725 m.put("principalName", approver);
726
727
728 List<Person> pList = KimApiServiceLocator.getPersonService().findPeople(m, false);
729 List<String> principalList = new ArrayList<String>();
730
731 if(pList == null || pList.isEmpty() ){
732
733
734 PrincipalContract tempPrincipal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(approver.trim());
735
736 if (tempPrincipal != null) {
737 principalList.add(tempPrincipal.getPrincipalId());
738 } else {
739
740 return new StringBuilder(whereClausePredicatePrefix + " 1 = 0 ").toString();
741 }
742 }
743
744 for(Person p: pList){
745 principalList.add(p.getPrincipalId());
746 }
747
748 Criteria crit = new Criteria("KREW_ACTN_TKN_T", "KREW_ACTN_TKN_T");
749 crit.in("PRNCPL_ID", principalList, String.class);
750
751 returnSql = whereClausePredicatePrefix +
752 " DOC_HDR.DOC_HDR_ID = KREW_ACTN_TKN_T.DOC_HDR_ID and upper(KREW_ACTN_TKN_T.ACTN_CD) in ('" +
753 KewApiConstants.ACTION_TAKEN_APPROVED_CD + "','" + KewApiConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + "')" +
754 " and " + crit.buildWhere();
755 }
756 return returnSql;
757 }
758
759 public String getApproverIdSql(String approverId, String whereClausePredicatePrefix) {
760 String returnSql = "";
761 if (StringUtils.isNotBlank(approverId)) {
762 Map<String, String> m = new HashMap<String, String>();
763 m.put("principalId", approverId);
764
765
766 List<Person> pList = KimApiServiceLocator.getPersonService().findPeople(m, false);
767 List<String> principalList = new ArrayList<String>();
768
769 if(pList == null || pList.isEmpty() ){
770
771 return new StringBuilder(whereClausePredicatePrefix + " 1 = 0 ").toString();
772 }
773
774 for(Person p: pList){
775 principalList.add(p.getPrincipalId());
776 }
777
778 Criteria crit = new Criteria("KREW_ACTN_TKN_T", "KREW_ACTN_TKN_T");
779 crit.in("PRNCPL_ID", principalList, String.class);
780
781 returnSql = whereClausePredicatePrefix +
782 " DOC_HDR.DOC_HDR_ID = KREW_ACTN_TKN_T.DOC_HDR_ID and upper(KREW_ACTN_TKN_T.ACTN_CD) in ('" +
783 KewApiConstants.ACTION_TAKEN_APPROVED_CD + "','" + KewApiConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + "')" +
784 " and " + crit.buildWhere();
785 }
786 return returnSql;
787 }
788
789 public String getDocTypeFullNameWhereSql(DocumentSearchCriteria criteria, String whereClausePredicatePrefix) {
790 List<String> documentTypeNamesToSearch = new ArrayList<String>();
791 String primaryDocumentTypeName = criteria.getDocumentTypeName();
792 if (StringUtils.isNotBlank(primaryDocumentTypeName)) {
793 documentTypeNamesToSearch.add(primaryDocumentTypeName);
794 }
795 documentTypeNamesToSearch.addAll(criteria.getAdditionalDocumentTypeNames());
796 StringBuilder returnSql = new StringBuilder("");
797 if (CollectionUtils.isNotEmpty(documentTypeNamesToSearch)) {
798 int index = 0;
799 for (String documentTypeName : documentTypeNamesToSearch) {
800 if (StringUtils.isNotBlank(documentTypeName)) {
801 String clause = index++ == 0 ? "" : " or ";
802 DocumentTypeService docSrv = KEWServiceLocator.getDocumentTypeService();
803 DocumentType docType = docSrv.findByNameCaseInsensitive(documentTypeName.trim());
804 if (docType != null) {
805 if (documentTypeName.contains("*") || documentTypeName.contains("%")) {
806 addDocumentTypeLikeNameToSearchOn(returnSql, documentTypeName.trim(), clause);
807 } else {
808 addDocumentTypeNameToSearchOn(returnSql, documentTypeName.trim(), clause);
809 }
810 if (docType.getChildrenDocTypes() != null) {
811 addChildDocumentTypes(returnSql, docType.getChildrenDocTypes());
812 }
813 } else{
814 addDocumentTypeLikeNameToSearchOn(returnSql, documentTypeName.trim(), clause);
815 }
816 }
817 }
818 }
819 if (returnSql.length() > 0) {
820 returnSql.insert(0, "(");
821 returnSql.insert(0, whereClausePredicatePrefix);
822 returnSql.append(")");
823 }
824 return returnSql.toString();
825 }
826
827 public void addChildDocumentTypes(StringBuilder whereSql, Collection<DocumentType> childDocumentTypes) {
828 for (DocumentType child : childDocumentTypes) {
829 addDocumentTypeNameToSearchOn(whereSql, child.getName());
830 addChildDocumentTypes(whereSql, child.getChildrenDocTypes());
831 }
832 }
833
834 public void addDocumentTypeNameToSearchOn(StringBuilder whereSql, String documentTypeName) {
835 this.addDocumentTypeNameToSearchOn(whereSql, documentTypeName, " or ");
836 }
837
838 public void addDocumentTypeNameToSearchOn(StringBuilder whereSql, String documentTypeName, String clause) {
839 whereSql.append(clause).append("upper(DOC1.DOC_TYP_NM) = '" + documentTypeName.toUpperCase() + "'");
840 }
841 public void addDocumentTypeLikeNameToSearchOn(StringBuilder whereSql, String documentTypeName, String clause) {
842 documentTypeName = documentTypeName.replace('*', '%');
843 whereSql.append(clause).append(" upper(DOC1.DOC_TYP_NM) LIKE '" + documentTypeName.toUpperCase() + "'");
844 }
845
846 public String getDocRouteNodeSql(String documentTypeFullName, String routeNodeName, RouteNodeLookupLogic docRouteLevelLogic, String whereClausePredicatePrefix) {
847
848
849 String returnSql = "";
850 if (StringUtils.isNotBlank(routeNodeName)) {
851 if (docRouteLevelLogic == null) {
852 docRouteLevelLogic = RouteNodeLookupLogic.EXACTLY;
853 }
854 StringBuilder routeNodeCriteria = new StringBuilder("and " + ROUTE_NODE_TABLE + ".NM ");
855 if (RouteNodeLookupLogic.EXACTLY == docRouteLevelLogic) {
856 routeNodeCriteria.append("= '" + getDbPlatform().escapeString(routeNodeName) + "' ");
857 } else {
858 routeNodeCriteria.append("in (");
859
860 StringBuilder routeNodeInCriteria = new StringBuilder();
861 boolean foundSpecifiedNode = false;
862 List<RouteNode> routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(getValidDocumentType(documentTypeFullName), true);
863 for (RouteNode routeNode : routeNodes) {
864 if (routeNodeName.equals(routeNode.getRouteNodeName())) {
865
866 foundSpecifiedNode = true;
867 continue;
868 }
869
870
871
872 if ( (!foundSpecifiedNode && RouteNodeLookupLogic.BEFORE == docRouteLevelLogic) ||
873 (foundSpecifiedNode && RouteNodeLookupLogic.AFTER == docRouteLevelLogic) ) {
874 if (routeNodeInCriteria.length() > 0) {
875 routeNodeInCriteria.append(", ");
876 }
877 routeNodeInCriteria.append("'" + routeNode.getRouteNodeName() + "'");
878 }
879 }
880 if (routeNodeInCriteria.length() > 0) {
881 routeNodeCriteria.append(routeNodeInCriteria);
882 } else {
883 routeNodeCriteria.append("''");
884 }
885 routeNodeCriteria.append(") ");
886 }
887 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() + " ";
888 }
889 return returnSql;
890 }
891
892 public String getDocumentStatusSql(List<DocumentStatus> documentStatuses, List<DocumentStatusCategory> categories, String whereClausePredicatePrefix) {
893 if (CollectionUtils.isEmpty(documentStatuses) && CollectionUtils.isEmpty(categories)) {
894 return whereClausePredicatePrefix + "DOC_HDR.DOC_HDR_STAT_CD != '" + DocumentStatus.INITIATED.getCode() + "'";
895 } else {
896
897 Set<DocumentStatus> statusesToInclude = new HashSet<DocumentStatus>(documentStatuses);
898
899
900 for (DocumentStatusCategory category : categories) {
901 Set<DocumentStatus> categoryStatuses = DocumentStatus.getStatusesForCategory(category);
902 statusesToInclude.addAll(categoryStatuses);
903 }
904
905 Set<String> statusCodes = new HashSet<String>();
906 for (DocumentStatus statusToInclude : statusesToInclude) {
907 statusCodes.add("'" + getDbPlatform().escapeString(statusToInclude.getCode()) + "'");
908 }
909 return whereClausePredicatePrefix + " DOC_HDR.DOC_HDR_STAT_CD in (" + StringUtils.join(statusCodes, ", ") +")";
910 }
911 }
912
913
914
915
916
917
918 public String getAppDocStatusesSql(List<String> appDocStatuses, String whereClausePredicatePrefix, int statusTransitionWhereClauseLength) {
919 if (CollectionUtils.isEmpty(appDocStatuses)) {
920 return "";
921 } else {
922 String inList = buildAppDocStatusInList(appDocStatuses);
923
924 if (statusTransitionWhereClauseLength > 0){
925 return whereClausePredicatePrefix + " STAT_TRAN.APP_DOC_STAT_TO" + inList;
926 } else {
927 return whereClausePredicatePrefix + " DOC_HDR.APP_DOC_STAT" + inList;
928 }
929 }
930 }
931
932 private String buildAppDocStatusInList(List<String> appDocStatuses) {
933 StringBuilder sql = new StringBuilder(" IN (");
934
935 boolean first = true;
936 for (String appDocStatus : appDocStatuses) {
937
938 if (first) {
939 first = false;
940 } else {
941 sql.append(",");
942 }
943
944 sql.append("'");
945 sql.append(getDbPlatform().escapeString(appDocStatus.trim()));
946 sql.append("'");
947 }
948
949 sql.append(")");
950
951 return sql.toString();
952 }
953
954 public String getGeneratedPredicatePrefix(int whereClauseSize) {
955 return (whereClauseSize > 0) ? " and " : " where ";
956 }
957
958 public String establishDateString(DateTime fromDate, DateTime toDate, String tableName, String tableAlias, String colName, String whereStatementClause) {
959
960 String fromDateValue = null;
961 if (fromDate != null) {
962 fromDateValue = CoreApiServiceLocator.getDateTimeService().toDateString(fromDate.toDate());
963 }
964
965 String toDateValue = null;
966 if (toDate != null) {
967 toDateValue = CoreApiServiceLocator.getDateTimeService().toDateString(toDate.toDate());
968 toDateValue += " 23:59:59";
969 }
970
971 String searchValue = null;
972 if (fromDateValue != null && toDateValue != null) {
973 searchValue = fromDateValue + " .. " + toDateValue;
974 } else if (fromDateValue != null) {
975 searchValue = ">= " + fromDateValue;
976 } else if (toDateValue != null) {
977 searchValue = "<= " + toDateValue;
978 } else {
979 return "";
980 }
981
982 Criteria crit = getSqlBuilder().createCriteria(colName, searchValue, tableName, tableAlias, java.sql.Date.class, true, true);
983 return new StringBuilder(whereStatementClause).append(crit.buildWhere()).toString();
984
985 }
986
987 public DatabasePlatform getDbPlatform() {
988 if (dbPlatform == null) {
989 dbPlatform = (DatabasePlatform) GlobalResourceLoader.getService(RiceConstants.DB_PLATFORM);
990 }
991 return dbPlatform;
992 }
993
994 public SqlBuilder getSqlBuilder() {
995 if(sqlBuilder == null){
996 sqlBuilder = new SqlBuilder();
997 sqlBuilder.setDbPlatform(getDbPlatform());
998 sqlBuilder.setDateTimeService(CoreApiServiceLocator.getDateTimeService());
999 }
1000 return this.sqlBuilder;
1001 }
1002
1003 public void setSqlBuilder(SqlBuilder sqlBuilder) {
1004 this.sqlBuilder = sqlBuilder;
1005 }
1006
1007
1008
1009
1010
1011
1012
1013 protected boolean isUsingAtLeastOneSearchAttribute(DocumentSearchCriteria criteria) {
1014 return criteria.getDocumentAttributeValues().size() > 0 || StringUtils.isNotBlank(criteria.getDocumentTypeName());
1015 }
1016
1017 }