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