1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.actionlist.service.impl;
17
18 import java.sql.Timestamp;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Date;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.kuali.rice.core.api.config.property.ConfigContext;
28 import org.kuali.rice.kew.actionitem.ActionItem;
29 import org.kuali.rice.kew.actionitem.OutboxItemActionListExtension;
30 import org.kuali.rice.kew.actionitem.dao.ActionItemDAO;
31 import org.kuali.rice.kew.actionlist.ActionListFilter;
32 import org.kuali.rice.kew.actionlist.dao.ActionListDAO;
33 import org.kuali.rice.kew.actionlist.service.ActionListService;
34 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
35 import org.kuali.rice.kew.actionrequest.Recipient;
36 import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
37 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
38 import org.kuali.rice.kew.doctype.bo.DocumentType;
39 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
40 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
41 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
42 import org.kuali.rice.kew.service.KEWServiceLocator;
43 import org.kuali.rice.kew.useroptions.UserOptions;
44 import org.kuali.rice.kew.useroptions.UserOptionsService;
45 import org.kuali.rice.kew.api.KewApiConstants;
46 import org.kuali.rice.kim.api.group.GroupService;
47 import org.kuali.rice.kim.api.identity.principal.Principal;
48 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
49
50
51
52
53
54
55 public class ActionListServiceImpl implements ActionListService {
56
57 protected final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(getClass());
58
59 private ActionListDAO actionListDAO;
60
61 private ActionItemDAO actionItemDAO;
62
63 public Collection<Recipient> findUserSecondaryDelegators(String principalId) {
64 return getActionItemDAO().findSecondaryDelegators(principalId);
65 }
66
67 public Collection<Recipient> findUserPrimaryDelegations(String principalId) {
68 return getActionItemDAO().findPrimaryDelegationRecipients(principalId);
69 }
70
71 public Collection<ActionItem> getActionList(String principalId, ActionListFilter filter) {
72 return getActionListDAO().getActionList(principalId, filter);
73 }
74
75 public Collection<ActionItem> getActionListForSingleDocument(String documentId) {
76 return getActionListDAO().getActionListForSingleDocument(documentId);
77 }
78
79 public void setActionListDAO(ActionListDAO actionListDAO) {
80 this.actionListDAO = actionListDAO;
81 }
82
83 public ActionListDAO getActionListDAO() {
84 return actionListDAO;
85 }
86
87 public boolean refreshActionList(String principalId) {
88 return KEWServiceLocator.getUserOptionsService().refreshActionList(principalId);
89 }
90
91 public void deleteActionItem(ActionItem actionItem) {
92 deleteActionItem(actionItem, false);
93 }
94
95 public void deleteActionItem(ActionItem actionItem, boolean forceIntoOutbox) {
96 try {
97 KEWServiceLocator.getUserOptionsService().saveRefreshUserOption(actionItem.getPrincipalId());
98 } catch (Exception e) {
99 LOG.error("error saving refreshUserOption", e);
100 }
101 getActionItemDAO().deleteActionItem(actionItem);
102
103 KEWServiceLocator.getNotificationService().removeNotification(Collections.singletonList(ActionItem.to(actionItem)));
104 this.saveOutboxItem(actionItem, forceIntoOutbox);
105 }
106
107 public void deleteByDocumentId(String documentId) {
108 Collection<ActionItem> actionItems = findByDocumentId(documentId);
109 for (Iterator<ActionItem> iter = actionItems.iterator(); iter.hasNext();) {
110 ActionItem actionItem = iter.next();
111 try {
112 KEWServiceLocator.getUserOptionsService().saveRefreshUserOption(actionItem.getPrincipalId());
113 } catch (Exception e) {
114 LOG.error("error saving refreshUserOption", e);
115 }
116 }
117 getActionItemDAO().deleteByDocumentId(documentId);
118 }
119
120 public Collection<ActionItem> findByDocumentId(String documentId) {
121 return getActionItemDAO().findByDocumentId(documentId);
122 }
123
124 public Collection<ActionItem> findByActionRequestId(String actionRequestId) {
125 return getActionItemDAO().findByActionRequestId(actionRequestId);
126 }
127
128 public Collection<ActionItem> findByWorkflowUserDocumentId(String workflowUserId, String documentId) {
129 return getActionItemDAO().findByWorkflowUserDocumentId(workflowUserId, documentId);
130 }
131
132 public Collection<ActionItem> findByDocumentTypeName(String documentTypeName) {
133 return getActionItemDAO().findByDocumentTypeName(documentTypeName);
134 }
135
136 public ActionItem createActionItemForActionRequest(ActionRequestValue actionRequest) {
137 ActionItem actionItem = new ActionItem();
138
139 DocumentRouteHeaderValue routeHeader = actionRequest.getRouteHeader();
140 DocumentType docType = routeHeader.getDocumentType();
141
142 actionItem.setActionRequestCd(actionRequest.getActionRequested());
143 actionItem.setActionRequestId(actionRequest.getActionRequestId());
144 actionItem.setDocName(docType.getName());
145 actionItem.setRoleName(actionRequest.getQualifiedRoleName());
146 actionItem.setPrincipalId(actionRequest.getPrincipalId());
147 actionItem.setDocumentId(actionRequest.getDocumentId());
148 actionItem.setDateAssigned(new Timestamp(new Date().getTime()));
149 actionItem.setDocHandlerURL(docType.getResolvedDocumentHandlerUrl());
150 actionItem.setDocLabel(docType.getLabel());
151 actionItem.setDocTitle(routeHeader.getDocTitle());
152 actionItem.setGroupId(actionRequest.getGroupId());
153 actionItem.setResponsibilityId(actionRequest.getResponsibilityId());
154 actionItem.setDelegationType(actionRequest.getDelegationType());
155 actionItem.setRequestLabel(actionRequest.getRequestLabel());
156
157 ActionRequestValue delegatorActionRequest = getActionRequestService().findDelegatorRequest(actionRequest);
158 if (delegatorActionRequest != null) {
159 actionItem.setDelegatorPrincipalId(delegatorActionRequest.getPrincipalId());
160 actionItem.setDelegatorGroupId(delegatorActionRequest.getGroupId());
161 }
162
163 return actionItem;
164 }
165
166
167 public void updateActionItemsForTitleChange(String documentId, String newTitle) {
168 Collection<ActionItem> items = getActionItemDAO().findByDocumentId(documentId);
169 for (Iterator<ActionItem> iterator = items.iterator(); iterator.hasNext();) {
170 ActionItem item = iterator.next();
171 item.setDocTitle(newTitle);
172 saveActionItem(item);
173 }
174 }
175
176 public void saveActionItem(ActionItem actionItem) {
177 KEWServiceLocator.getUserOptionsService().saveRefreshUserOption(actionItem.getPrincipalId());
178 getActionItemDAO().saveActionItem(actionItem);
179 }
180
181 public ActionItemDAO getActionItemDAO() {
182 return actionItemDAO;
183 }
184
185 public ActionRequestService getActionRequestService() {
186 return (ActionRequestService) KEWServiceLocator.getActionRequestService();
187 }
188
189 public GroupService getGroupService(){
190 return KimApiServiceLocator.getGroupService();
191 }
192
193 public void setActionItemDAO(ActionItemDAO actionItemDAO) {
194 this.actionItemDAO = actionItemDAO;
195 }
196
197
198 public void validateActionItem(ActionItem actionItem) {
199 List<WorkflowServiceErrorImpl> errors = new ArrayList<WorkflowServiceErrorImpl>();
200 String principalId = actionItem.getPrincipalId();
201 if (principalId == null || principalId.trim().equals("")) {
202 errors.add(new WorkflowServiceErrorImpl("ActionItem person null.", "actionitem.personid.empty", actionItem
203 .getId().toString()));
204 } else {
205 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
206 if (principal == null) {
207 errors.add(new WorkflowServiceErrorImpl("ActionItem person invalid.", "actionitem.personid.invalid",
208 actionItem.getId().toString()));
209 }
210 }
211
212 if (actionItem.getDateAssigned() == null) {
213 errors.add(new WorkflowServiceErrorImpl("ActionItem date assigned empty.", "actionitem.dateassigned.empty",
214 actionItem.getId().toString()));
215 }
216
217 String actionRequestCd = actionItem.getActionRequestCd();
218 if (actionRequestCd == null || actionRequestCd.trim().equals("")) {
219 errors.add(new WorkflowServiceErrorImpl("ActionItem action request cd empty.",
220 "actionitem.actionrequestcd.empty", actionItem.getId().toString()));
221 } else if (!KewApiConstants.ACTION_REQUEST_CD.containsKey(actionRequestCd)) {
222 errors.add(new WorkflowServiceErrorImpl("ActionItem action request cd invalid.",
223 "actionitem.actionrequestcd.invalid", actionItem.getId().toString()));
224 }
225
226 if (actionItem.getActionRequestId() == null) {
227 errors.add(new WorkflowServiceErrorImpl("ActionItem action request id empty.",
228 "actionitem.actionrequestid.empty", actionItem.getId().toString()));
229 }
230
231 if (actionItem.getDocumentId() == null) {
232 errors.add(new WorkflowServiceErrorImpl("ActionItem Document id empty.", "actionitem.documentid.empty",
233 actionItem.getId().toString()));
234 } else if (KEWServiceLocator.getRouteHeaderService().getRouteHeader(actionItem.getDocumentId()) == null) {
235 errors.add(new WorkflowServiceErrorImpl("ActionItem Document id invalid.", "actionitem.documentid.invalid",
236 actionItem.getId().toString()));
237 }
238
239 String docTypeName = actionItem.getDocName();
240 DocumentType docType = null;
241 if (docTypeName == null || docTypeName.trim().equals("")) {
242 errors.add(new WorkflowServiceErrorImpl("ActionItem doctypename empty.", "actionitem.doctypename.empty",
243 actionItem.getId().toString()));
244 } else {
245 docType = KEWServiceLocator.getDocumentTypeService().findByName(actionItem.getDocName());
246 if (docType == null) {
247 errors.add(new WorkflowServiceErrorImpl("ActionItem doctypename invalid.", "actionitem.doctypename.invalid",
248 actionItem.getId().toString()));
249 }
250 }
251
252 if (actionItem.getDocLabel() == null || actionItem.getDocLabel().trim().equals("")) {
253 errors.add(new WorkflowServiceErrorImpl("ActionItem doctypelabel empty.", "actionitem.doctypelabel.empty",
254 actionItem.getId().toString()));
255 } else if (docType != null && !docType.getLabel().equals(actionItem.getDocLabel())) {
256 errors.add(new WorkflowServiceErrorImpl("ActionItem doctypelabel no match.", "actionitem.doctypelabel.nomatch",
257 actionItem.getId().toString()));
258 }
259
260
261 if (StringUtils.isNotBlank(docType.getResolvedDocumentHandlerUrl())) {
262 if (actionItem.getDocHandlerURL() == null || actionItem.getDocHandlerURL().trim().equals("")) {
263 errors.add(new WorkflowServiceErrorImpl("ActionItem doc handler url empty.", "actionitem.dochdrurl.empty",
264 actionItem.getId().toString()));
265 } else if (docType != null && !docType.getResolvedDocumentHandlerUrl().equals(actionItem.getDocHandlerURL())) {
266 errors.add(new WorkflowServiceErrorImpl("ActionItem doc handler url no match.", "actionitem.dochdrurl.nomatch",
267 actionItem.getId().toString()));
268 }
269 } else {
270
271 if (StringUtils.isNotBlank(actionItem.getDocHandlerURL())) {
272 errors.add(new WorkflowServiceErrorImpl("ActionItem doc handler url not empty.", "actionitem.dochdrurl.not.empty",
273 actionItem.getId().toString()));
274 }
275 }
276
277 if (!errors.isEmpty()) {
278 throw new WorkflowServiceErrorException("ActionItem Validation Error", errors);
279 }
280 }
281
282 public ActionItem findByActionItemId(String actionItemId) {
283 return getActionItemDAO().findByActionItemId(actionItemId);
284 }
285
286 public int getCount(String principalId) {
287 return getActionListDAO().getCount(principalId);
288 }
289
290 public void saveRefreshUserOption(String principalId) {
291 KEWServiceLocator.getUserOptionsService().saveRefreshUserOption(principalId);
292 }
293
294
295
296
297
298
299
300 public Collection<ActionItem> getOutbox(String principalId, ActionListFilter filter) {
301 return this.getActionListDAO().getOutbox(principalId, filter);
302 }
303
304 public Collection<ActionItem> getOutboxItemsByDocumentType(String documentTypeName) {
305 return this.getActionItemDAO().getOutboxItemsByDocumentType(documentTypeName);
306 }
307
308
309
310
311
312
313 public void removeOutboxItems(String principalId, List<String> outboxItems) {
314 this.getActionListDAO().removeOutboxItems(principalId, outboxItems);
315 }
316
317 public void saveOutboxItem(ActionItem actionItem) {
318 saveOutboxItem(actionItem, false);
319 }
320
321
322
323
324
325
326
327 public void saveOutboxItem(ActionItem actionItem, boolean forceIntoOutbox) {
328 UserOptionsService userOptionsService = KEWServiceLocator.getUserOptionsService();
329 Boolean isUsingOutBox = true;
330 List<UserOptions> options = userOptionsService.findByUserQualified(actionItem.getPrincipalId(), KewApiConstants.USE_OUT_BOX);
331 if (options == null || options.isEmpty()){
332 isUsingOutBox = true;
333 } else {
334 for (Iterator iter = options.iterator(); iter.hasNext();) {
335 UserOptions u = (UserOptions) iter.next();
336 if (u.getOptionVal() == null || !(u.getOptionVal().equals("yes"))){
337 isUsingOutBox = false;
338 }
339 }
340 }
341
342 if (isUsingOutBox
343 && ConfigContext.getCurrentContextConfig().getOutBoxOn()
344 && getActionListDAO().getOutboxByDocumentIdUserId(actionItem.getDocumentId(), actionItem.getPrincipalId()) == null
345 && !KEWServiceLocator.getRouteHeaderService().getRouteHeader(actionItem.getDocumentId()).getDocRouteStatus().equals(
346 KewApiConstants.ROUTE_HEADER_SAVED_CD)) {
347
348
349 ActionRequestValue actionRequest = KEWServiceLocator.getActionRequestService().findByActionRequestId(
350 actionItem.getActionRequestId());
351 ActionTakenValue actionTaken = actionRequest.getActionTaken();
352
353 if (forceIntoOutbox || (actionTaken != null && actionTaken.getPrincipalId().equals(actionItem.getPrincipalId()))) {
354 this.getActionListDAO().saveOutboxItem(new OutboxItemActionListExtension(actionItem));
355 }
356
357 }
358 }
359
360 public Collection<ActionItem> findByPrincipalId(String principalId) {
361 return getActionItemDAO().findByPrincipalId(principalId);
362 }
363
364 }