1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.actionlist.dao.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.ojb.broker.PersistenceBroker;
20 import org.apache.ojb.broker.accesslayer.LookupException;
21 import org.apache.ojb.broker.query.Criteria;
22 import org.apache.ojb.broker.query.QueryByCriteria;
23 import org.kuali.rice.core.api.delegation.DelegationType;
24 import org.kuali.rice.kew.actionitem.ActionItem;
25 import org.kuali.rice.kew.actionitem.ActionItemActionListExtension;
26 import org.kuali.rice.kew.actionitem.OutboxItemActionListExtension;
27 import org.kuali.rice.kew.actionlist.ActionListFilter;
28 import org.kuali.rice.kew.actionlist.dao.ActionListDAO;
29 import org.kuali.rice.kew.api.WorkflowRuntimeException;
30 import org.kuali.rice.kew.doctype.bo.DocumentType;
31 import org.kuali.rice.kew.service.KEWServiceLocator;
32 import org.kuali.rice.kew.api.KewApiConstants;
33 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
34 import org.springmodules.orm.ojb.PersistenceBrokerCallback;
35 import org.springmodules.orm.ojb.support.PersistenceBrokerDaoSupport;
36
37 import java.sql.Connection;
38 import java.sql.PreparedStatement;
39 import java.sql.ResultSet;
40 import java.sql.SQLException;
41 import java.sql.Timestamp;
42 import java.util.ArrayList;
43 import java.util.Calendar;
44 import java.util.Collection;
45 import java.util.Date;
46 import java.util.HashMap;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Map;
50
51
52
53
54
55
56 public class ActionListDAOOjbImpl extends PersistenceBrokerDaoSupport implements ActionListDAO {
57
58 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ActionListDAOOjbImpl.class);
59
60 public Collection<ActionItemActionListExtension> getActionList(String principalId, ActionListFilter filter) {
61 return getActionItemsInActionList(ActionItemActionListExtension.class, principalId, filter);
62 }
63
64 public Collection<ActionItemActionListExtension> getActionListForSingleDocument(String documentId) {
65 LOG.debug("getting action list for document id " + documentId);
66 Criteria crit = new Criteria();
67 crit.addEqualTo("documentId", documentId);
68 Collection<ActionItemActionListExtension> collection = this.getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(ActionItemActionListExtension.class, crit));
69 LOG.debug("found " + collection.size() + " action items for document id " + documentId);
70 return createActionListForRouteHeader(collection);
71 }
72
73 private Criteria setUpActionListCriteria(String principalId, ActionListFilter filter) {
74 LOG.debug("setting up Action List criteria");
75 Criteria crit = new Criteria();
76 boolean filterOn = false;
77 String filteredByItems = "";
78
79 if (filter.getActionRequestCd() != null && !"".equals(filter.getActionRequestCd().trim()) && !filter.getActionRequestCd().equals(KewApiConstants.ALL_CODE)) {
80 if (filter.isExcludeActionRequestCd()) {
81 crit.addNotEqualTo("actionRequestCd", filter.getActionRequestCd());
82 } else {
83 crit.addEqualTo("actionRequestCd", filter.getActionRequestCd());
84 }
85 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
86 filteredByItems += "Action Requested";
87 }
88
89 if (filter.getCreateDateFrom() != null || filter.getCreateDateTo() != null) {
90 if (filter.isExcludeCreateDate()) {
91 if (filter.getCreateDateFrom() != null && filter.getCreateDateTo() != null) {
92 crit.addNotBetween("routeHeader.createDate", new Timestamp(beginningOfDay(filter.getCreateDateFrom()).getTime()), new Timestamp(endOfDay(filter.getCreateDateTo()).getTime()));
93 } else if (filter.getCreateDateFrom() != null && filter.getCreateDateTo() == null) {
94 crit.addLessOrEqualThan("routeHeader.createDate", new Timestamp(beginningOfDay(filter.getCreateDateFrom()).getTime()));
95 } else if (filter.getCreateDateFrom() == null && filter.getCreateDateTo() != null) {
96 crit.addGreaterOrEqualThan("routeHeader.createDate", new Timestamp(endOfDay(filter.getCreateDateTo()).getTime()));
97 }
98 } else {
99 if (filter.getCreateDateFrom() != null && filter.getCreateDateTo() != null) {
100 crit.addBetween("routeHeader.createDate", new Timestamp(beginningOfDay(filter.getCreateDateFrom()).getTime()), new Timestamp(endOfDay(filter.getCreateDateTo()).getTime()));
101 } else if (filter.getCreateDateFrom() != null && filter.getCreateDateTo() == null) {
102 crit.addGreaterOrEqualThan("routeHeader.createDate", new Timestamp(beginningOfDay(filter.getCreateDateFrom()).getTime()));
103 } else if (filter.getCreateDateFrom() == null && filter.getCreateDateTo() != null) {
104 crit.addLessOrEqualThan("routeHeader.createDate", new Timestamp(endOfDay(filter.getCreateDateTo()).getTime()));
105 }
106 }
107 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
108 filteredByItems += "Date Created";
109 }
110
111 if (filter.getDocRouteStatus() != null && !"".equals(filter.getDocRouteStatus().trim()) && !filter.getDocRouteStatus().equals(KewApiConstants.ALL_CODE)) {
112 if (filter.isExcludeRouteStatus()) {
113 crit.addNotEqualTo("routeHeader.docRouteStatus", filter.getDocRouteStatus());
114 } else {
115 crit.addEqualTo("routeHeader.docRouteStatus", filter.getDocRouteStatus());
116 }
117 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
118 filteredByItems += "Document Route Status";
119 }
120
121 if (filter.getDocumentTitle() != null && !"".equals(filter.getDocumentTitle().trim())) {
122 String docTitle = filter.getDocumentTitle();
123 if (docTitle.trim().endsWith("*")) {
124 docTitle = docTitle.substring(0, docTitle.length() - 1);
125 }
126
127 if (filter.isExcludeDocumentTitle()) {
128 crit.addNotLike("docTitle", "%" + docTitle + "%");
129 } else {
130 crit.addLike("docTitle", "%" + docTitle + "%");
131 }
132 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
133 filteredByItems += "Document Title";
134 }
135
136 if (filter.getDocumentType() != null && !"".equals(filter.getDocumentType().trim())) {
137 if (filter.isExcludeDocumentType()) {
138 crit.addNotLike("docName", "%" + filter.getDocumentType() + "%");
139 } else {
140 String documentTypeName = filter.getDocumentType();
141 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(documentTypeName);
142 if (documentType == null) {
143 crit.addLike("docName", "%" + filter.getDocumentType() + "%");
144 } else {
145
146 Criteria docTypeCrit = new Criteria();
147 constructDocumentTypeCriteria(docTypeCrit, documentType);
148 crit.addAndCriteria(docTypeCrit);
149 }
150 }
151 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
152 filteredByItems += "Document Type";
153 }
154
155 if (filter.getLastAssignedDateFrom() != null || filter.getLastAssignedDateTo() != null) {
156 if (filter.isExcludeLastAssignedDate()) {
157 if (filter.getLastAssignedDateFrom() != null && filter.getLastAssignedDateTo() != null) {
158 crit.addNotBetween("dateAssigned", new Timestamp(beginningOfDay(filter.getLastAssignedDateFrom()).getTime()), new Timestamp(endOfDay(filter.getLastAssignedDateTo()).getTime()));
159 } else if (filter.getLastAssignedDateFrom() != null && filter.getLastAssignedDateTo() == null) {
160 crit.addLessOrEqualThan("dateAssigned", new Timestamp(beginningOfDay(filter.getLastAssignedDateFrom()).getTime()));
161 } else if (filter.getLastAssignedDateFrom() == null && filter.getLastAssignedDateTo() != null) {
162 crit.addGreaterOrEqualThan("dateAssigned", new Timestamp(endOfDay(filter.getLastAssignedDateTo()).getTime()));
163 }
164 } else {
165 if (filter.getLastAssignedDateFrom() != null && filter.getLastAssignedDateTo() != null) {
166 crit.addBetween("dateAssigned", new Timestamp(beginningOfDay(filter.getLastAssignedDateFrom()).getTime()), new Timestamp(endOfDay(filter.getLastAssignedDateTo()).getTime()));
167 } else if (filter.getLastAssignedDateFrom() != null && filter.getLastAssignedDateTo() == null) {
168 crit.addGreaterOrEqualThan("dateAssigned", new Timestamp(beginningOfDay(filter.getLastAssignedDateFrom()).getTime()));
169 } else if (filter.getLastAssignedDateFrom() == null && filter.getLastAssignedDateTo() != null) {
170 crit.addLessOrEqualThan("dateAssigned", new Timestamp(endOfDay(filter.getLastAssignedDateTo()).getTime()));
171 }
172 }
173 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
174 filteredByItems += "Date Last Assigned";
175 }
176
177 filter.setGroupId(null);
178 if (filter.getGroupIdString() != null && !"".equals(filter.getGroupIdString().trim()) && !filter.getGroupIdString().trim().equals(KewApiConstants.NO_FILTERING)) {
179
180 filter.setGroupId(filter.getGroupIdString().trim());
181
182 if (filter.isExcludeGroupId()) {
183 Criteria critNotEqual = new Criteria();
184 critNotEqual.addNotEqualTo("groupId", filter.getGroupId());
185 Criteria critNull = new Criteria();
186 critNull.addIsNull("groupId");
187 critNotEqual.addOrCriteria(critNull);
188 crit.addAndCriteria(critNotEqual);
189 } else {
190 crit.addEqualTo("groupId", filter.getGroupId());
191 }
192 filteredByItems += filteredByItems.length() > 0 ? ", " : "";
193 filteredByItems += "Action Request Workgroup";
194 }
195
196 if (filteredByItems.length() > 0) {
197 filterOn = true;
198 }
199
200 boolean addedDelegationCriteria = false;
201 if (StringUtils.isBlank(filter.getDelegationType()) && StringUtils.isBlank(filter.getPrimaryDelegateId()) && StringUtils.isBlank(filter.getDelegatorId())) {
202 crit.addEqualTo("principalId", principalId);
203 addedDelegationCriteria = true;
204 } else if ((StringUtils.isNotBlank(filter.getDelegationType()) && DelegationType.PRIMARY.getCode().equals(filter.getDelegationType()))
205 || StringUtils.isNotBlank(filter.getPrimaryDelegateId())) {
206
207 if ((StringUtils.isBlank(filter.getPrimaryDelegateId())) || (filter.getPrimaryDelegateId().trim().equals(KewApiConstants.ALL_CODE))) {
208
209 Criteria userCrit = new Criteria();
210 Criteria groupCrit = new Criteria();
211 Criteria orCrit = new Criteria();
212 userCrit.addEqualTo("delegatorPrincipalId", principalId);
213 List<String> delegatorGroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(
214 principalId);
215 if (delegatorGroupIds != null && !delegatorGroupIds.isEmpty()) {
216 groupCrit.addIn("delegatorGroupId", delegatorGroupIds);
217 }
218 orCrit.addOrCriteria(userCrit);
219 orCrit.addOrCriteria(groupCrit);
220 crit.addAndCriteria(orCrit);
221 crit.addEqualTo("delegationType", DelegationType.PRIMARY.getCode());
222 filter.setDelegationType(DelegationType.PRIMARY.getCode());
223 filter.setExcludeDelegationType(false);
224 addToFilterDescription(filteredByItems, "Primary Delegator Id");
225 addedDelegationCriteria = true;
226 filterOn = true;
227 } else if (!filter.getPrimaryDelegateId().trim().equals(KewApiConstants.PRIMARY_DELEGATION_DEFAULT)) {
228
229 crit.addEqualTo("principalId", filter.getPrimaryDelegateId());
230 Criteria userCrit = new Criteria();
231 Criteria groupCrit = new Criteria();
232 Criteria orCrit = new Criteria();
233 userCrit.addEqualTo("delegatorPrincipalId", principalId);
234 List<String> delegatorGroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(
235 principalId);
236 if (delegatorGroupIds != null && !delegatorGroupIds.isEmpty()) {
237 groupCrit.addIn("delegatorGroupId", delegatorGroupIds);
238 }
239 orCrit.addOrCriteria(userCrit);
240 orCrit.addOrCriteria(groupCrit);
241 crit.addAndCriteria(orCrit);
242 crit.addEqualTo("delegationType", DelegationType.PRIMARY.getCode());
243 filter.setDelegationType(DelegationType.PRIMARY.getCode());
244 filter.setExcludeDelegationType(false);
245 addToFilterDescription(filteredByItems, "Primary Delegator Id");
246 addedDelegationCriteria = true;
247 filterOn = true;
248 }
249 }
250 if (!addedDelegationCriteria && ( (StringUtils.isNotBlank(filter.getDelegationType()) && DelegationType.SECONDARY.getCode().equals(filter.getDelegationType()))
251 || StringUtils.isNotBlank(filter.getDelegatorId()) )) {
252
253 crit.addEqualTo("principalId", principalId);
254 if (StringUtils.isBlank(filter.getDelegatorId())) {
255 filter.setDelegationType(DelegationType.SECONDARY.getCode());
256
257 if (!filter.isExcludeDelegationType()) {
258 crit.addEqualTo("delegationType", DelegationType.SECONDARY.getCode());
259 addToFilterDescription(filteredByItems, "Secondary Delegator Id");
260 addedDelegationCriteria = true;
261 filterOn = true;
262 }
263 } else if (filter.getDelegatorId().trim().equals(KewApiConstants.ALL_CODE)) {
264
265 crit.addEqualTo("delegationType", DelegationType.SECONDARY.getCode());
266 filter.setDelegationType(DelegationType.SECONDARY.getCode());
267 filter.setExcludeDelegationType(false);
268 addToFilterDescription(filteredByItems, "Secondary Delegator Id");
269 addedDelegationCriteria = true;
270 filterOn = true;
271 } else if (!filter.getDelegatorId().trim().equals(
272 KewApiConstants.DELEGATION_DEFAULT)) {
273
274 filter.setDelegationType(DelegationType.SECONDARY.getCode());
275 filter.setExcludeDelegationType(false);
276 Criteria userCrit = new Criteria();
277 Criteria groupCrit = new Criteria();
278 if (filter.isExcludeDelegatorId()) {
279 Criteria userNull = new Criteria();
280 userCrit.addNotEqualTo("delegatorPrincipalId", filter.getDelegatorId());
281 userNull.addIsNull("delegatorPrincipalId");
282 userCrit.addOrCriteria(userNull);
283 Criteria groupNull = new Criteria();
284 groupCrit.addNotEqualTo("delegatorGroupId", filter.getDelegatorId());
285 groupNull.addIsNull("delegatorGroupId");
286 groupCrit.addOrCriteria(groupNull);
287 crit.addAndCriteria(userCrit);
288 crit.addAndCriteria(groupCrit);
289 } else {
290 Criteria orCrit = new Criteria();
291 userCrit.addEqualTo("delegatorPrincipalId", filter.getDelegatorId());
292 groupCrit.addEqualTo("delegatorGroupId", filter.getDelegatorId());
293 orCrit.addOrCriteria(userCrit);
294 orCrit.addOrCriteria(groupCrit);
295 crit.addAndCriteria(orCrit);
296 }
297 addToFilterDescription(filteredByItems, "Secondary Delegator Id");
298 addedDelegationCriteria = true;
299 filterOn = true;
300 }
301 }
302
303
304 if (!addedDelegationCriteria) {
305 crit.addEqualTo("principalId", principalId);
306 filter.setDelegationType(DelegationType.SECONDARY.getCode());
307 filter.setExcludeDelegationType(true);
308 Criteria critNotEqual = new Criteria();
309 Criteria critNull = new Criteria();
310 critNotEqual.addNotEqualTo("delegationType", DelegationType.SECONDARY.getCode());
311 critNull.addIsNull("delegationType");
312 critNotEqual.addOrCriteria(critNull);
313 crit.addAndCriteria(critNotEqual);
314 }
315
316 if (! "".equals(filteredByItems)) {
317 filteredByItems = "Filtered by " + filteredByItems;
318 }
319 filter.setFilterLegend(filteredByItems);
320 filter.setFilterOn(filterOn);
321
322 LOG.debug("returning from Action List criteria");
323 return crit;
324 }
325
326 private void constructDocumentTypeCriteria(Criteria criteria, DocumentType documentType) {
327
328 Criteria docTypeBaseCrit = new Criteria();
329 docTypeBaseCrit.addEqualTo("docName", documentType.getName());
330 criteria.addOrCriteria(docTypeBaseCrit);
331 Collection children = documentType.getChildrenDocTypes();
332 if (children != null) {
333 for (Iterator iterator = children.iterator(); iterator.hasNext();) {
334 DocumentType childDocumentType = (DocumentType) iterator.next();
335 constructDocumentTypeCriteria(criteria, childDocumentType);
336 }
337 }
338 }
339
340 private void addToFilterDescription(String filterDescription, String labelToAdd) {
341 filterDescription += filterDescription.length() > 0 ? ", " : "";
342 filterDescription += labelToAdd;
343 }
344
345 private static final String ACTION_LIST_COUNT_QUERY = "select count(distinct(ai.doc_hdr_id)) from krew_actn_itm_t ai where ai.PRNCPL_ID = ? and (ai.dlgn_typ is null or ai.dlgn_typ = 'P')";
346
347 public int getCount(final String workflowId) {
348 return (Integer)getPersistenceBrokerTemplate().execute(new PersistenceBrokerCallback() {
349 public Object doInPersistenceBroker(PersistenceBroker broker) {
350 PreparedStatement statement = null;
351 ResultSet resultSet = null;
352 try {
353 Connection connection = broker.serviceConnectionManager().getConnection();
354 statement = connection.prepareStatement(ACTION_LIST_COUNT_QUERY);
355 statement.setString(1, workflowId);
356 resultSet = statement.executeQuery();
357 if (!resultSet.next()) {
358 throw new WorkflowRuntimeException("Error determining Action List Count.");
359 }
360 return resultSet.getInt(1);
361 } catch (SQLException e) {
362 throw new WorkflowRuntimeException("Error determining Action List Count.", e);
363 } catch (LookupException e) {
364 throw new WorkflowRuntimeException("Error determining Action List Count.", e);
365 } finally {
366 if (statement != null) {
367 try {
368 statement.close();
369 } catch (SQLException e) {}
370 }
371 if (resultSet != null) {
372 try {
373 resultSet.close();
374 } catch (SQLException e) {}
375 }
376 }
377 }
378 });
379 }
380
381 private static final String MAX_ACTION_ITEM_DATE_ASSIGNED_AND_ACTION_LIST_COUNT_AND_QUERY = "select max(ASND_DT) as max_date, count(distinct(doc_hdr_id)) as total_records"
382 + " from ("
383 + " select ASND_DT,doc_hdr_id "
384 + " from KREW_ACTN_ITM_T where prncpl_id=? "
385 + " group by ASND_DT,doc_hdr_id "
386 + " ) T";
387
388
389
390
391
392
393
394 public List<Object> getMaxActionItemDateAssignedAndCountForUser(final String principalId){
395 return (List<Object>)getPersistenceBrokerTemplate().execute(new PersistenceBrokerCallback() {
396 public Object doInPersistenceBroker(PersistenceBroker broker) {
397 PreparedStatement statement = null;
398 ResultSet resultSet = null;
399 List<Object> result = new ArrayList<Object>();
400 try {
401 Connection connection = broker.serviceConnectionManager().getConnection();
402 statement = connection.prepareStatement(MAX_ACTION_ITEM_DATE_ASSIGNED_AND_ACTION_LIST_COUNT_AND_QUERY);
403 statement.setString(1, principalId);
404 resultSet = statement.executeQuery();
405 if (!resultSet.next()) {
406 throw new WorkflowRuntimeException("Error determining Action List Count and Max Action Item Id.");
407 }
408 else{
409 result.add(resultSet.getTimestamp(1));
410 result.add(resultSet.getInt(2));
411 }
412 return result;
413 } catch (SQLException e) {
414 throw new WorkflowRuntimeException("Error determining Action List Count and Max Action Item Id.", e);
415 } catch (LookupException e) {
416 throw new WorkflowRuntimeException("Error determining Action List Count and Max Action Item Id.", e);
417 } finally {
418 if (statement != null) {
419 try {
420 statement.close();
421 } catch (SQLException e) {}
422 }
423 if (resultSet != null) {
424 try {
425 resultSet.close();
426 } catch (SQLException e) {}
427 }
428 }
429 }
430 });
431 }
432
433
434
435
436
437
438
439
440 private <T extends ActionItemActionListExtension> Collection<T> createActionListForUser(Collection<T> actionItems) {
441 Map<String, T> actionItemMap = new HashMap<String, T>();
442 ActionListPriorityComparator comparator = new ActionListPriorityComparator();
443 for (T potentialActionItem: actionItems) {
444 T existingActionItem = actionItemMap.get(potentialActionItem.getDocumentId());
445 if (existingActionItem == null || comparator.compare(potentialActionItem, existingActionItem) > 0) {
446 actionItemMap.put(potentialActionItem.getDocumentId(), potentialActionItem);
447 }
448 }
449 return actionItemMap.values();
450 }
451
452
453
454
455
456
457
458
459 private Collection<ActionItemActionListExtension> createActionListForRouteHeader(Collection<ActionItemActionListExtension> actionItems) {
460 Map<String, ActionItemActionListExtension> actionItemMap = new HashMap<String, ActionItemActionListExtension>();
461 ActionListPriorityComparator comparator = new ActionListPriorityComparator();
462 for (ActionItemActionListExtension potentialActionItem: actionItems) {
463 ActionItemActionListExtension existingActionItem = actionItemMap.get(potentialActionItem.getPrincipalId());
464 if (existingActionItem == null || comparator.compare(potentialActionItem, existingActionItem) > 0) {
465 actionItemMap.put(potentialActionItem.getPrincipalId(), potentialActionItem);
466 }
467 }
468 return actionItemMap.values();
469 }
470
471 private <T extends ActionItemActionListExtension> Collection<T> getActionItemsInActionList(Class<T> objectsToRetrieve, String principalId, ActionListFilter filter) {
472 LOG.debug("getting action list for user " + principalId);
473 Criteria crit = null;
474 if (filter == null) {
475 crit = new Criteria();
476 crit.addEqualTo("principalId", principalId);
477 } else {
478 crit = setUpActionListCriteria(principalId, filter);
479 }
480 LOG.debug("running query to get action list for criteria " + crit);
481 Collection<T> collection = this.getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(objectsToRetrieve, crit));
482 LOG.debug("found " + collection.size() + " action items for user " + principalId);
483 return createActionListForUser(collection);
484 }
485
486 public Collection<OutboxItemActionListExtension> getOutbox(String principalId, ActionListFilter filter) {
487 return getActionItemsInActionList(OutboxItemActionListExtension.class, principalId, filter);
488 }
489
490
491
492
493
494
495
496 public void removeOutboxItems(String principalId, List<String> outboxItems) {
497 Criteria crit = new Criteria();
498 crit.addIn("id", outboxItems);
499 getPersistenceBrokerTemplate().deleteByQuery(new QueryByCriteria(OutboxItemActionListExtension.class, crit));
500 }
501
502
503
504
505
506
507 public void saveOutboxItem(OutboxItemActionListExtension outboxItem) {
508 this.getPersistenceBrokerTemplate().store(outboxItem);
509 }
510
511
512
513
514
515
516 public OutboxItemActionListExtension getOutboxByDocumentId(String documentId) {
517 Criteria crit = new Criteria();
518 crit.addEqualTo("documentId", documentId);
519 return (OutboxItemActionListExtension)getPersistenceBrokerTemplate().getObjectByQuery(new QueryByCriteria(OutboxItemActionListExtension.class, crit));
520 }
521
522 public OutboxItemActionListExtension getOutboxByDocumentIdUserId(String documentId, String userId) {
523 Criteria crit = new Criteria();
524 crit.addEqualTo("documentId", documentId);
525 crit.addEqualTo("principalId", userId);
526 return (OutboxItemActionListExtension)getPersistenceBrokerTemplate().getObjectByQuery(new QueryByCriteria(OutboxItemActionListExtension.class, crit));
527 }
528
529 private Date beginningOfDay(Date date) {
530 Calendar cal = Calendar.getInstance();
531 cal.setTime(date);
532 cal.set(Calendar.HOUR_OF_DAY, 0);
533 cal.set(Calendar.MINUTE, 0);
534 cal.set(Calendar.SECOND, 0);
535 return cal.getTime();
536 }
537
538 private Date endOfDay(Date date) {
539 Calendar cal = Calendar.getInstance();
540 cal.setTime(date);
541 cal.set(Calendar.HOUR_OF_DAY, 23);
542 cal.set(Calendar.MINUTE, 59);
543 cal.set(Calendar.SECOND, 59);
544 return cal.getTime();
545 }
546
547 }