1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.routeheader.dao.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.lang.exception.ExceptionUtils;
20 import org.apache.ojb.broker.OptimisticLockException;
21 import org.apache.ojb.broker.PersistenceBroker;
22 import org.apache.ojb.broker.accesslayer.LookupException;
23 import org.apache.ojb.broker.query.Criteria;
24 import org.apache.ojb.broker.query.QueryByCriteria;
25 import org.apache.ojb.broker.query.QueryFactory;
26 import org.apache.ojb.broker.query.ReportQueryByCriteria;
27 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
28 import org.kuali.rice.core.api.util.RiceConstants;
29 import org.kuali.rice.core.framework.persistence.platform.DatabasePlatform;
30 import org.kuali.rice.kew.actionitem.ActionItem;
31 import org.kuali.rice.kew.actionlist.service.ActionListService;
32 import org.kuali.rice.kew.api.WorkflowRuntimeException;
33 import org.kuali.rice.kew.api.action.ActionRequestStatus;
34 import org.kuali.rice.kew.api.exception.LockingException;
35 import org.kuali.rice.kew.docsearch.SearchableAttributeValue;
36 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
37 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent;
38 import org.kuali.rice.kew.routeheader.dao.DocumentRouteHeaderDAO;
39 import org.kuali.rice.kew.service.KEWServiceLocator;
40 import org.springframework.dao.CannotAcquireLockException;
41 import org.springmodules.orm.ojb.OjbFactoryUtils;
42 import org.springmodules.orm.ojb.PersistenceBrokerCallback;
43 import org.springmodules.orm.ojb.support.PersistenceBrokerDaoSupport;
44
45 import java.sql.Connection;
46 import java.sql.PreparedStatement;
47 import java.sql.ResultSet;
48 import java.sql.SQLException;
49 import java.sql.Statement;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Set;
55
56 public class DocumentRouteHeaderDAOOjbImpl extends PersistenceBrokerDaoSupport implements DocumentRouteHeaderDAO {
57
58 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentRouteHeaderDAOOjbImpl.class);
59
60 public void saveRouteHeader(DocumentRouteHeaderValue routeHeader) {
61 if ( LOG.isDebugEnabled() ) {
62 LOG.debug( "About to Save the route Header: " + routeHeader.getDocumentId() + " / version=" + routeHeader.getVersionNumber() );
63 DocumentRouteHeaderValue currHeader = findRouteHeader(routeHeader.getDocumentId());
64 if ( currHeader != null ) {
65 LOG.debug( "Current Header Version: " + currHeader.getVersionNumber() );
66
67
68
69 } else {
70 LOG.debug( "Current Header: null" );
71 }
72 LOG.debug( ExceptionUtils.getStackTrace(new Throwable()) );
73 }
74 try {
75 getPersistenceBrokerTemplate().store(routeHeader);
76 routeHeader.getDocumentContent().setDocumentId(routeHeader.getDocumentId());
77 getPersistenceBrokerTemplate().store(routeHeader.getDocumentContent());
78 } catch ( RuntimeException ex ) {
79 if ( ex.getCause() instanceof OptimisticLockException ) {
80 LOG.error( "Optimistic Locking Exception saving document header or content. Offending object: " + ((OptimisticLockException)ex.getCause()).getSourceObject()
81 + "; DocumentId = " + routeHeader.getDocumentId() + " ; Version Number = " + routeHeader.getVersionNumber());
82 }
83 LOG.error( "Unable to save document header or content. Route Header: " + routeHeader, ex );
84 throw ex;
85 }
86 }
87
88 public DocumentRouteHeaderValueContent getContent(String documentId) {
89 Criteria crit = new Criteria();
90 crit.addEqualTo("documentId", documentId);
91 return (DocumentRouteHeaderValueContent)this.getPersistenceBrokerTemplate().getObjectByQuery(new QueryByCriteria(DocumentRouteHeaderValueContent.class, crit));
92 }
93
94 public void clearRouteHeaderSearchValues(String documentId) {
95 Criteria crit = new Criteria();
96 crit.addEqualTo("documentId", documentId);
97 QueryByCriteria query = new QueryByCriteria(SearchableAttributeValue.class, crit);
98 query.addOrderByAscending("searchableAttributeValueId");
99 Collection<SearchableAttributeValue> results = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
100 if (!results.isEmpty()) {
101 for (SearchableAttributeValue srchAttrVal: results) {
102 this.getPersistenceBrokerTemplate().delete(srchAttrVal);
103 }
104 }
105 }
106
107 public Collection<SearchableAttributeValue> findSearchableAttributeValues(String documentId) {
108 Criteria crit = new Criteria();
109 crit.addEqualTo("documentId", documentId);
110 QueryByCriteria query = new QueryByCriteria(SearchableAttributeValue.class, crit);
111 query.addOrderByAscending("searchableAttributeValueId");
112 return this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
113 }
114
115 public void lockRouteHeader(final String documentId, final boolean wait) {
116
117
118
119
120
121 this.getPersistenceBrokerTemplate().execute(new PersistenceBrokerCallback() {
122 public Object doInPersistenceBroker(PersistenceBroker broker) {
123 PreparedStatement statement = null;
124 try {
125 Connection connection = broker.serviceConnectionManager().getConnection();
126 String sql = getPlatform().getLockRouteHeaderQuerySQL(documentId, wait);
127 statement = connection.prepareStatement(sql);
128 statement.setString(1, documentId);
129 statement.execute();
130 return null;
131 } catch (SQLException e) {
132 throw new LockingException("Could not aquire lock on document, documentId=" + documentId, e);
133 } catch (LookupException e) {
134 throw new LockingException("Could not aquire lock on document, documentId=" + documentId, e);
135 } catch (CannotAcquireLockException e) {
136 throw new LockingException("Could not aquire lock on document, documentId=" + documentId, e);
137 } finally {
138 if (statement != null) {
139 try {
140 statement.close();
141 } catch (SQLException e) {
142 }
143 }
144 }
145 }
146 });
147
148 }
149
150 public DocumentRouteHeaderValue findRouteHeader(String documentId) {
151 return findRouteHeader(documentId, false);
152 }
153
154 public DocumentRouteHeaderValue findRouteHeader(String documentId, boolean clearCache) {
155 Criteria crit = new Criteria();
156 crit.addEqualTo("documentId", documentId);
157 if (clearCache) {
158 this.getPersistenceBrokerTemplate().clearCache();
159 }
160 return (DocumentRouteHeaderValue) this.getPersistenceBrokerTemplate().getObjectByQuery(new QueryByCriteria(DocumentRouteHeaderValue.class, crit));
161 }
162
163 public Collection<DocumentRouteHeaderValue> findRouteHeaders(Collection<String> documentIds) {
164 return findRouteHeaders(documentIds, false);
165 }
166
167 public Collection<DocumentRouteHeaderValue> findRouteHeaders(Collection<String> documentIds, boolean clearCache) {
168 if (documentIds == null || documentIds.isEmpty()) {
169 return null;
170 }
171 Criteria crit = new Criteria();
172 crit.addIn("documentId", documentIds);
173 if (clearCache) {
174 this.getPersistenceBrokerTemplate().clearCache();
175 }
176 return (Collection<DocumentRouteHeaderValue>) this.getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(DocumentRouteHeaderValue.class, crit));
177 }
178
179 public void deleteRouteHeader(DocumentRouteHeaderValue routeHeader) {
180 this.getPersistenceBrokerTemplate().delete(routeHeader);
181 }
182
183 public String getNextDocumentId() {
184 return (String)this.getPersistenceBrokerTemplate().execute(new PersistenceBrokerCallback() {
185 public Object doInPersistenceBroker(PersistenceBroker broker) {
186 return getPlatform().getNextValSQL("KREW_DOC_HDR_S", broker).toString();
187 }
188 });
189 }
190
191 protected DatabasePlatform getPlatform() {
192 return (DatabasePlatform)GlobalResourceLoader.getService(RiceConstants.DB_PLATFORM);
193 }
194
195 public Collection<String> findPendingByResponsibilityIds(Set<String> responsibilityIds) {
196 Collection<String> documentIds = new ArrayList();
197 if (responsibilityIds.isEmpty()) {
198 return documentIds;
199 }
200 PersistenceBroker broker = null;
201 Connection conn = null;
202 Statement statement = null;
203 ResultSet rs = null;
204 try {
205 broker = getPersistenceBroker(false);
206 conn = broker.serviceConnectionManager().getConnection();
207 String respIds = "('";
208 int index = 0;
209 for (String responsibilityId : responsibilityIds) {
210 respIds += responsibilityId + (index == responsibilityIds.size()-1 ? "" : "','");
211 index++;
212 }
213 respIds += "')";
214 String query = "SELECT DISTINCT(doc_hdr_id) FROM KREW_ACTN_RQST_T "+
215 "WHERE (STAT_CD='" +
216 ActionRequestStatus.INITIALIZED.getCode()+
217 "' OR STAT_CD='"+
218 ActionRequestStatus.ACTIVATED.getCode()+
219 "') AND RSP_ID IN "+respIds;
220 LOG.debug("Query to find pending documents for requeue: " + query);
221 statement = conn.createStatement();
222 rs = statement.executeQuery(query);
223 while (rs.next()) {
224 documentIds.add(rs.getString(1));
225 }
226 } catch (SQLException sqle) {
227 LOG.error("SQLException: " + sqle.getMessage(), sqle);
228 throw new WorkflowRuntimeException(sqle);
229 } catch (LookupException le) {
230 LOG.error("LookupException: " + le.getMessage(), le);
231 throw new WorkflowRuntimeException(le);
232 } finally {
233 if (rs != null) {
234 try {
235 rs.close();
236 } catch (SQLException e) {
237 LOG.warn("Could not close result set.");
238 }
239 }
240 if (statement != null) {
241 try {
242 statement.close();
243 } catch (SQLException e) {
244 LOG.warn("Could not close statement.");
245 }
246 }
247 try {
248 if (broker != null) {
249 OjbFactoryUtils.releasePersistenceBroker(broker, this.getPersistenceBrokerTemplate().getPbKey());
250 }
251 } catch (Exception e) {
252 LOG.error("Failed closing connection: " + e.getMessage(), e);
253 }
254 }
255 return documentIds;
256 }
257
258 public boolean hasSearchableAttributeValue(String documentId, String searchableAttributeKey, String searchableAttributeValue) {
259 Criteria crit = new Criteria();
260 crit.addEqualTo("documentId", documentId);
261 crit.addEqualTo("searchableAttributeKey", searchableAttributeKey);
262 Collection results = getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(SearchableAttributeValue.class, crit));
263 if (!results.isEmpty()) {
264 for (Iterator iterator = results.iterator(); iterator.hasNext();) {
265 SearchableAttributeValue attribute = (SearchableAttributeValue) iterator.next();
266 if (StringUtils.equals(attribute.getSearchableAttributeDisplayValue(), searchableAttributeValue)) {
267 return true;
268 }
269 }
270 }
271 return false;
272 }
273
274 public String getApplicationIdByDocumentId(String documentId) {
275 if (documentId == null) {
276 throw new IllegalArgumentException("Encountered a null document ID.");
277 }
278 String applicationId = null;
279 PersistenceBroker broker = null;
280 Connection conn = null;
281 PreparedStatement statement = null;
282 ResultSet rs = null;
283 try {
284 broker = this.getPersistenceBroker(false);
285 conn = broker.serviceConnectionManager().getConnection();
286 String query = "SELECT DT.APPL_ID FROM KREW_DOC_TYP_T DT, KREW_DOC_HDR_T DH "+
287 "WHERE DH.DOC_TYP_ID=DT.DOC_TYP_ID AND "+
288 "DH.DOC_HDR_ID=?";
289 statement = conn.prepareStatement(query);
290 statement.setString(1, documentId);
291 rs = statement.executeQuery();
292 if (rs.next()) {
293 applicationId = rs.getString(1);
294 if (rs.wasNull()) {
295 applicationId = null;
296 }
297 }
298 } catch (SQLException sqle) {
299 LOG.error("SQLException: " + sqle.getMessage(), sqle);
300 throw new WorkflowRuntimeException(sqle);
301 } catch (LookupException le) {
302 LOG.error("LookupException: " + le.getMessage(), le);
303 throw new WorkflowRuntimeException(le);
304 } finally {
305 if (rs != null) {
306 try {
307 rs.close();
308 } catch (SQLException e) {
309 LOG.warn("Could not close result set.");
310 }
311 }
312 if (statement != null) {
313 try {
314 statement.close();
315 } catch (SQLException e) {
316 LOG.warn("Could not close statement.");
317 }
318 }
319 try {
320 if (broker != null) {
321 OjbFactoryUtils.releasePersistenceBroker(broker, this.getPersistenceBrokerTemplate().getPbKey());
322 }
323 } catch (Exception e) {
324 LOG.error("Failed closing connection: " + e.getMessage(), e);
325 }
326 }
327 return applicationId;
328 }
329
330 public String getDocumentStatus(String documentId) {
331 Criteria crit = new Criteria();
332 crit.addEqualTo("documentId", documentId);
333 ReportQueryByCriteria query = QueryFactory.newReportQuery(DocumentRouteHeaderValue.class, crit);
334 query.setAttributes(new String[] { "docRouteStatus" });
335 String status = null;
336 Iterator iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
337 while (iter.hasNext()) {
338 Object[] row = (Object[]) iter.next();
339 status = (String)row[0];
340 }
341 return status;
342 }
343
344 public String getAppDocId(String documentId) {
345 Criteria crit = new Criteria();
346 crit.addEqualTo("documentId", documentId);
347 ReportQueryByCriteria query = QueryFactory.newReportQuery(DocumentRouteHeaderValue.class, crit);
348 query.setAttributes(new String[] { "appDocId" });
349 String appDocId = null;
350 Iterator iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
351 while (iter.hasNext()) {
352 Object[] row = (Object[]) iter.next();
353 appDocId = (String)row[0];
354 }
355 return appDocId;
356 }
357
358 public String getAppDocStatus(String documentId) {
359 Criteria crit = new Criteria();
360 crit.addEqualTo("documentId", documentId);
361 ReportQueryByCriteria query = QueryFactory.newReportQuery(DocumentRouteHeaderValue.class, crit);
362 query.setAttributes(new String[] { "appDocStatus" });
363 String appDocStatus = null;
364 Iterator iter = getPersistenceBrokerTemplate().getReportQueryIteratorByQuery(query);
365 while (iter.hasNext()) {
366 Object[] row = (Object[]) iter.next();
367 appDocStatus = (String)row[0];
368 }
369 return appDocStatus;
370 }
371
372 public void save(SearchableAttributeValue searchableAttributeValue) {
373 getPersistenceBrokerTemplate().store(searchableAttributeValue);
374 }
375
376 public Collection findByDocTypeAndAppId(String documentTypeName,
377 String appId) {
378 Collection documentIds = new ArrayList();
379
380 PersistenceBroker broker = null;
381 Connection conn = null;
382 ResultSet rs = null;
383 try {
384 broker = getPersistenceBroker(false);
385 conn = broker.serviceConnectionManager().getConnection();
386
387 String query =
388 "SELECT DISTINCT " +
389 " (docHdr.doc_hdr_id) " +
390 "FROM " +
391 " KREW_DOC_HDR_T docHdr, " +
392 " KREW_DOC_TYP_T docTyp " +
393 "WHERE " +
394 " docHdr.APP_DOC_ID = ? " +
395 " AND docHdr.DOC_TYP_ID = docTyp.DOC_TYP_ID " +
396 " AND docTyp.DOC_TYP_NM = ?";
397
398 LOG.debug("Query to find documents by app id: " + query);
399
400 PreparedStatement stmt = conn.prepareStatement(query);
401 stmt.setString(1, appId);
402 stmt.setString(2, documentTypeName);
403 rs = stmt.executeQuery();
404
405 while (rs.next()) {
406 documentIds.add(new String(rs.getString(1)));
407 }
408 rs.close();
409 } catch (SQLException sqle) {
410 LOG.error("SQLException: " + sqle.getMessage(), sqle);
411 throw new WorkflowRuntimeException(sqle);
412 } catch (LookupException le) {
413 LOG.error("LookupException: " + le.getMessage(), le);
414 throw new WorkflowRuntimeException(le);
415 } finally {
416 try {
417 if (broker != null) {
418 OjbFactoryUtils.releasePersistenceBroker(broker, this.getPersistenceBrokerTemplate().getPbKey());
419 }
420 } catch (Exception e) {
421 LOG.error("Failed closing connection: " + e.getMessage(), e);
422 }
423 }
424 return documentIds;
425 }
426
427 }