1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.docsearch.dao.impl;
18
19 import java.sql.Connection;
20 import java.sql.ResultSet;
21 import java.sql.SQLException;
22 import java.sql.Statement;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.ojb.broker.PersistenceBroker;
28 import org.apache.ojb.broker.accesslayer.LookupException;
29 import org.kuali.rice.kew.docsearch.DocSearchCriteriaDTO;
30 import org.kuali.rice.kew.docsearch.DocSearchDTO;
31 import org.kuali.rice.kew.docsearch.DocumentSearchGenerator;
32 import org.kuali.rice.kew.docsearch.StandardDocumentSearchGenerator;
33 import org.kuali.rice.kew.docsearch.dao.DocumentSearchDAO;
34 import org.kuali.rice.kew.doctype.service.DocumentSecurityService;
35 import org.kuali.rice.kew.service.KEWServiceLocator;
36 import org.kuali.rice.kew.util.KEWConstants;
37 import org.kuali.rice.kew.util.PerformanceLogger;
38 import org.kuali.rice.kew.util.Utilities;
39 import org.kuali.rice.kns.util.KNSConstants;
40 import org.springmodules.orm.ojb.OjbFactoryUtils;
41 import org.springmodules.orm.ojb.support.PersistenceBrokerDaoSupport;
42
43
44
45
46
47
48
49
50
51 public class DocumentSearchDAOOjbImpl extends PersistenceBrokerDaoSupport implements DocumentSearchDAO {
52
53 public static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentSearchDAOOjbImpl.class);
54
55 private static final int DEFAULT_FETCH_MORE_ITERATION_LIMIT = 10;
56
57 public List<DocSearchDTO> getListBoundedByCritera(DocumentSearchGenerator documentSearchGenerator, DocSearchCriteriaDTO criteria, String principalId) {
58 return getList(documentSearchGenerator, criteria, criteria.getThreshold(), principalId);
59 }
60
61 public List<DocSearchDTO> getList(DocumentSearchGenerator documentSearchGenerator, DocSearchCriteriaDTO criteria, String principalId) {
62 return getList(documentSearchGenerator, criteria, Integer.valueOf(getSearchResultCap(documentSearchGenerator)), principalId);
63 }
64
65 private List<DocSearchDTO> getList(DocumentSearchGenerator documentSearchGenerator, DocSearchCriteriaDTO criteria, Integer searchResultCap, String principalId) {
66 LOG.debug("start getList");
67 DocumentSecurityService documentSecurityService = KEWServiceLocator.getDocumentSecurityService();
68 List docList = new ArrayList();
69 PersistenceBroker broker = null;
70 Connection conn = null;
71 Statement statement = null;
72 Statement searchAttributeStatement = null;
73 ResultSet rs = null;
74 try {
75 broker = getPersistenceBroker(false);
76 conn = broker.serviceConnectionManager().getConnection();
77 statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
78 criteria.setThreshold(searchResultCap);
79 if (searchResultCap != null) {
80 int fetchLimit = getFetchMoreIterationLimit() * searchResultCap.intValue();
81 criteria.setFetchLimit(Integer.valueOf(fetchLimit));
82 statement.setFetchSize(searchResultCap.intValue() + 1);
83 statement.setMaxRows(fetchLimit + 1);
84 } else {
85 criteria.setFetchLimit(null);
86 }
87 PerformanceLogger perfLog = new PerformanceLogger();
88 String sql = documentSearchGenerator.generateSearchSql(criteria);
89 perfLog.log("Time to generate search sql from documentSearchGenerator class: " + documentSearchGenerator.getClass().getName(), true);
90 LOG.info("Executing document search with statement max rows: " + statement.getMaxRows());
91 LOG.info("Executing document search with statement fetch size: " + statement.getFetchSize());
92 perfLog = new PerformanceLogger();
93 rs = statement.executeQuery(sql);
94 perfLog.log("Time to execute doc search database query.", true);
95
96 searchAttributeStatement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
97
98 if(documentSearchGenerator.isProcessResultSet()){
99 docList = documentSearchGenerator.processResultSet(searchAttributeStatement, rs, criteria, principalId);
100 }else{
101 docList = new StandardDocumentSearchGenerator().processResultSet(searchAttributeStatement, rs, criteria, principalId);
102 }
103
104 } catch (SQLException sqle) {
105 String errorMsg = "SQLException: " + sqle.getMessage();
106 LOG.error("getList() " + errorMsg, sqle);
107 throw new RuntimeException(errorMsg, sqle);
108 } catch (LookupException le) {
109 String errorMsg = "LookupException: " + le.getMessage();
110 LOG.error("getList() " + errorMsg, le);
111 throw new RuntimeException(errorMsg, le);
112 } finally {
113 if (rs != null) {
114 try {
115 rs.close();
116 } catch (SQLException e) {
117 LOG.warn("Could not close result set.");
118 }
119 }
120 if (statement != null) {
121 try {
122 statement.close();
123 } catch (SQLException e) {
124 LOG.warn("Could not close statement.");
125 }
126 }
127 if (searchAttributeStatement != null) {
128 try {
129 searchAttributeStatement.close();
130 } catch (SQLException e) {
131 LOG.warn("Could not close search attribute statement.");
132 }
133 }
134 if (broker != null) {
135 try {
136 OjbFactoryUtils.releasePersistenceBroker(broker, this.getPersistenceBrokerTemplate().getPbKey());
137 } catch (Exception e) {
138 LOG.error("Failed closing connection: " + e.getMessage(), e);
139 }
140 }
141 }
142
143 LOG.info("end getlist");
144 return docList;
145 }
146
147 private int getSearchResultCap(DocumentSearchGenerator docSearchGenerator) {
148 int resultCap = docSearchGenerator.getDocumentSearchResultSetLimit();
149 String resultCapValue = Utilities.getKNSParameterValue(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.DOCUMENT_SEARCH_DETAIL_TYPE, KEWConstants.DOC_SEARCH_RESULT_CAP);
150 if (!StringUtils.isBlank(resultCapValue)) {
151 try {
152 Integer maxResultCap = Integer.parseInt(resultCapValue);
153 if (resultCap > maxResultCap) {
154 LOG.warn("Document Search Generator (" + docSearchGenerator.getClass().getName() + ") gives result set cap of " + resultCap + " which is greater than parameter " + KEWConstants.DOC_SEARCH_RESULT_CAP + " value of " + maxResultCap);
155 resultCap = maxResultCap;
156 } else if (maxResultCap <= 0) {
157 LOG.warn(KEWConstants.DOC_SEARCH_RESULT_CAP + " was less than or equal to zero. Please use a positive integer.");
158 }
159 } catch (NumberFormatException e) {
160 LOG.warn(KEWConstants.DOC_SEARCH_RESULT_CAP + " is not a valid number. Value was " + resultCapValue);
161 }
162 }
163 return resultCap;
164 }
165
166
167 private int getFetchMoreIterationLimit() {
168 int fetchMoreLimit = DEFAULT_FETCH_MORE_ITERATION_LIMIT;
169 String fetchMoreLimitValue = Utilities.getKNSParameterValue(KEWConstants.KEW_NAMESPACE, KNSConstants.DetailTypes.DOCUMENT_SEARCH_DETAIL_TYPE, KEWConstants.DOC_SEARCH_FETCH_MORE_ITERATION_LIMIT);
170 if (!StringUtils.isBlank(fetchMoreLimitValue)) {
171 try {
172 fetchMoreLimit = Integer.parseInt(fetchMoreLimitValue);
173 if (fetchMoreLimit < 0) {
174 LOG.warn(KEWConstants.DOC_SEARCH_FETCH_MORE_ITERATION_LIMIT + " was less than zero. Please use a value greater than or equal to zero.");
175 fetchMoreLimit = DEFAULT_FETCH_MORE_ITERATION_LIMIT;
176 }
177 } catch (NumberFormatException e) {
178 LOG.warn(KEWConstants.DOC_SEARCH_FETCH_MORE_ITERATION_LIMIT + " is not a valid number. Value was " + fetchMoreLimitValue);
179 }
180 }
181 return fetchMoreLimit;
182 }
183
184
185
186
187
188 }