View Javadoc

1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.impl.document;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.joda.time.DateTime;
21  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
22  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
23  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
24  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
25  import org.kuali.rice.kew.api.action.ActionRequest;
26  import org.kuali.rice.kew.api.action.ActionTaken;
27  import org.kuali.rice.kew.api.doctype.RouteNode;
28  import org.kuali.rice.kew.api.document.Document;
29  import org.kuali.rice.kew.api.document.DocumentContent;
30  import org.kuali.rice.kew.api.document.DocumentDetail;
31  import org.kuali.rice.kew.api.document.DocumentLink;
32  import org.kuali.rice.kew.api.document.DocumentStatus;
33  import org.kuali.rice.kew.api.document.WorkflowDocumentService;
34  import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
35  import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
36  import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
37  import org.kuali.rice.kew.dto.DTOConverter;
38  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
39  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent;
40  import org.kuali.rice.kew.routeheader.DocumentStatusTransition;
41  import org.kuali.rice.kew.service.KEWServiceLocator;
42  
43  import javax.jws.WebParam;
44  import java.math.BigDecimal;
45  import java.sql.Timestamp;
46  import java.util.ArrayList;
47  import java.util.Collection;
48  import java.util.Collections;
49  import java.util.HashMap;
50  import java.util.LinkedHashSet;
51  import java.util.List;
52  import java.util.Map;
53  import java.util.Set;
54  
55  /**
56   * 
57   * @author Kuali Rice Team (rice.collab@kuali.org)
58   *
59   */
60  public class WorkflowDocumentServiceImpl implements WorkflowDocumentService {
61  
62  	private static final Logger LOG = Logger.getLogger(WorkflowDocumentServiceImpl.class);
63  	
64  	@Override
65  	public Document getDocument(String documentId) {
66  		if (StringUtils.isBlank(documentId)) {
67  			throw new RiceIllegalArgumentException("documentId was blank or null");
68  		}
69  		DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
70  		return DocumentRouteHeaderValue.to(documentBo);
71  	}
72  
73  	@Override
74  	public boolean doesDocumentExist(String documentId) {
75  	    if (StringUtils.isBlank(documentId)) {
76              throw new RiceIllegalArgumentException("documentId was blank or null");
77          }
78  	    DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
79  	    return documentBo != null;
80  	}
81  
82      @Override
83      public DocumentDetail getDocumentDetailByAppId(String documentTypeName, String appId) {
84          if (StringUtils.isEmpty(documentTypeName)) {
85              throw new RiceIllegalArgumentException("documentTypeName was blank or null");
86          }
87          if (StringUtils.isEmpty(appId)) {
88              throw new RiceIllegalArgumentException("appId was blank or null");
89          }
90  
91          Collection documentIds = KEWServiceLocator.getRouteHeaderService().findByDocTypeAndAppId(documentTypeName, appId);
92          if(documentIds==null||documentIds.isEmpty()){
93              throw new RiceIllegalStateException("No RouteHeader Ids found for documentTypName: " + documentTypeName + ", appId: " + appId);
94          }
95          if(documentIds.size()>1){
96              throw new RiceIllegalStateException("Multiple RouteHeader Ids found for documentTypName: " + documentTypeName + ", appId: " + appId);
97  		}
98  
99          return getDocumentDetail((String)documentIds.iterator().next());
100 	}
101 
102     public RouteNodeInstance getRouteNodeInstance(String nodeInstanceId)  {
103         if (StringUtils.isEmpty(nodeInstanceId)) {
104             throw new RiceIllegalArgumentException("nodeInstanceId was blank or null");
105         }
106         if ( LOG.isDebugEnabled() ) {
107         	LOG.debug("Fetching RouteNodeInstanceVO [id="+nodeInstanceId+"]");
108         }
109         org.kuali.rice.kew.engine.node.RouteNodeInstance nodeInstance = KEWServiceLocator.getRouteNodeService().findRouteNodeInstanceById(nodeInstanceId);
110         return org.kuali.rice.kew.engine.node.RouteNodeInstance.to(nodeInstance);
111     }
112 
113     @Override
114     public DocumentStatus getDocumentStatus(String documentId) {
115         if (StringUtils.isEmpty(documentId)) {
116             throw new RiceIllegalArgumentException("documentId was blank or null");
117         }
118         String documentStatus = KEWServiceLocator.getRouteHeaderService().getDocumentStatus(documentId);
119         if (StringUtils.isEmpty(documentStatus)) {
120             throw new RiceIllegalStateException("DocumentStatus not found for documentId: " + documentId);
121         }
122         return DocumentStatus.fromCode(documentStatus);
123     }
124 
125     @Override
126     public String getApplicationDocumentId(String documentId) {
127         if (StringUtils.isEmpty(documentId)) {
128             throw new RiceIllegalArgumentException("documentId was blank or null");
129         }
130  	 	return KEWServiceLocator.getRouteHeaderService().getAppDocId(documentId);
131  	}
132 
133     @Override
134     public String getApplicationDocumentStatus(String documentId)
135             throws RiceIllegalArgumentException {
136         if (StringUtils.isEmpty(documentId)) {
137             throw new RiceIllegalArgumentException("documentId was blank or null");
138         }
139         return KEWServiceLocator.getRouteHeaderService().getAppDocStatus(documentId);
140     }
141 
142     @Override
143     public DocumentSearchResults documentSearch(String principalId, DocumentSearchCriteria criteria) {
144         if (criteria == null) {
145             throw new RiceIllegalArgumentException("criteria was null");
146         }
147         return KEWServiceLocator.getDocumentSearchService().lookupDocuments(principalId, criteria);
148     }
149 
150     @Override
151     public List<String> getSearchableAttributeStringValuesByKey(String documentId, String key) {
152         if (StringUtils.isEmpty(documentId)) {
153             throw new RiceIllegalArgumentException("documentId was blank or null");
154         }
155         if (StringUtils.isEmpty(key)) {
156             throw new RiceIllegalArgumentException("key was blank or null");
157         }
158 		return KEWServiceLocator.getRouteHeaderService().getSearchableAttributeStringValuesByKey(documentId, key);
159 	}
160 
161     @Override
162 	public List<DateTime> getSearchableAttributeDateTimeValuesByKey(String documentId, String key) {
163 		if (StringUtils.isEmpty(documentId)) {
164             throw new RiceIllegalArgumentException("documentId was blank or null");
165         }
166         if (StringUtils.isEmpty(key)) {
167             throw new RiceIllegalArgumentException("key was blank or null");
168         }
169 
170         List<Timestamp> results = KEWServiceLocator.getRouteHeaderService().getSearchableAttributeDateTimeValuesByKey(documentId, key);
171         if (results == null) {
172             return null;
173         }
174         List<DateTime> dateTimes = new ArrayList<DateTime>();
175 
176 		for(Timestamp time : results) {
177             dateTimes.add(new DateTime(time.getTime()));
178         }
179         return dateTimes;
180 	}
181 
182     @Override
183 	public List<BigDecimal> getSearchableAttributeFloatValuesByKey(String documentId, String key) {
184         if (StringUtils.isEmpty(documentId)) {
185             throw new RiceIllegalArgumentException("documentId was blank or null");
186         }
187         if (StringUtils.isEmpty(key)) {
188             throw new RiceIllegalArgumentException("key was blank or null");
189         }
190 		return KEWServiceLocator.getRouteHeaderService().getSearchableAttributeFloatValuesByKey(documentId, key);
191 	}
192 
193     @Override
194     public List<Long> getSearchableAttributeLongValuesByKey(String documentId, String key) {
195         if (StringUtils.isEmpty(documentId)) {
196             throw new RiceIllegalArgumentException("documentId was blank or null");
197         }
198         if (StringUtils.isEmpty(key)) {
199             throw new RiceIllegalArgumentException("key was blank or null");
200         }
201 		return KEWServiceLocator.getRouteHeaderService().getSearchableAttributeLongValuesByKey(documentId, key);
202 	}
203 	
204 	@Override
205 	public DocumentContent getDocumentContent(String documentId) {
206 		if (StringUtils.isBlank(documentId)) {
207 			throw new RiceIllegalArgumentException("documentId was blank or null");
208 		}
209 		DocumentRouteHeaderValueContent content = KEWServiceLocator.getRouteHeaderService().getContent(documentId);
210 		return DocumentRouteHeaderValueContent.to(content);
211 	}
212 
213 	@Override
214 	public List<ActionRequest> getRootActionRequests(String documentId) {
215         if (StringUtils.isBlank(documentId)) {
216 			throw new RiceIllegalArgumentException("documentId was blank or null");
217 		}
218 		List<ActionRequest> actionRequests = new ArrayList<ActionRequest>();
219 		List<ActionRequestValue> actionRequestBos = KEWServiceLocator.getActionRequestService().findAllRootActionRequestsByDocumentId(documentId);
220 		for (ActionRequestValue actionRequestBo : actionRequestBos) {
221 			actionRequests.add(ActionRequestValue.to(actionRequestBo));
222 		}
223 		return Collections.unmodifiableList(actionRequests);
224 	}
225 	
226 	@Override
227 	public List<ActionRequest> getPendingActionRequests(String documentId) {
228 		if (StringUtils.isBlank(documentId)) {
229 			throw new RiceIllegalArgumentException("documentId was blank or null");
230 		}
231 		List<ActionRequest> actionRequests = new ArrayList<ActionRequest>();
232 		List<ActionRequestValue> actionRequestBos = KEWServiceLocator.getActionRequestService().findAllPendingRequests(documentId);
233 		for (ActionRequestValue actionRequestBo : actionRequestBos) {
234 			actionRequests.add(ActionRequestValue.to(actionRequestBo));
235 		}
236 		return Collections.unmodifiableList(actionRequests);
237 	}
238 	
239 	@Override
240 	public List<ActionRequest> getActionRequestsForPrincipalAtNode(String documentId, String nodeName,
241             String principalId) {
242         if (StringUtils.isBlank(documentId)) {
243         	throw new RiceIllegalArgumentException("documentId was null or blank");
244         }
245         if ( LOG.isDebugEnabled() ) {
246         	LOG.debug("Fetching ActionRequests [docId="+documentId+", nodeName="+nodeName+", principalId="+principalId+"]");
247         }
248         List<ActionRequestValue> actionRequestBos = KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(documentId);
249         List<ActionRequestValue> matchingActionRequests = new ArrayList<ActionRequestValue>();
250         for (ActionRequestValue actionRequestValue : actionRequestBos) {
251             if (actionRequestMatches(actionRequestValue, nodeName, principalId)) {
252                 matchingActionRequests.add(actionRequestValue);
253             }
254         }
255         List<ActionRequest> actionRequests = new ArrayList<ActionRequest>(matchingActionRequests.size());
256         for (ActionRequestValue matchingActionRequest : matchingActionRequests) {
257         	actionRequests.add(ActionRequestValue.to(matchingActionRequest));
258         }
259         return actionRequests;
260     }
261 	
262     protected boolean actionRequestMatches(ActionRequestValue actionRequest, String nodeName, String principalId) {
263         boolean matchesUserId = true;  // assume a match in case user is empty
264         boolean matchesNodeName = true;  // assume a match in case node name is empty
265         if (StringUtils.isNotBlank(nodeName)) {
266             matchesNodeName = nodeName.equals(actionRequest.getPotentialNodeName());
267         }
268         if (principalId != null) {
269             matchesUserId = actionRequest.isRecipientRoutedRequest(principalId);
270         }
271         return matchesNodeName && matchesUserId;
272     }
273 
274 
275 	@Override
276 	public List<ActionTaken> getActionsTaken(String documentId) {
277         if (StringUtils.isEmpty(documentId)) {
278             throw new RiceIllegalArgumentException("documentId is null or empty.");
279         }
280 		List<ActionTaken> actionTakens = new ArrayList<ActionTaken>();
281 		Collection<ActionTakenValue> actionTakenBos = KEWServiceLocator.getActionTakenService().findByDocumentId(documentId);
282 		for (ActionTakenValue actionTakenBo : actionTakenBos) {
283 			actionTakens.add(ActionTakenValue.to(actionTakenBo));
284 		}
285 		return actionTakens;
286 	}
287 
288     @Override
289     public List<ActionTaken> _getActionsTaken(String documentId) {
290         return getActionsTaken(documentId);
291     }
292 
293     @Override
294     public List<ActionTaken> getAllActionsTaken(String documentId){
295         if(StringUtils.isEmpty(documentId)){
296             throw new RiceIllegalArgumentException("documentId is null or empty.");
297         }
298 
299 		List<ActionTaken> actionsTaken = new ArrayList<ActionTaken>();
300         Collection<ActionTakenValue> actionTakenBos = KEWServiceLocator.getActionTakenService().findByDocumentIdIgnoreCurrentInd(documentId);
301 		for (ActionTakenValue actionTakenBo : actionTakenBos) {
302 			actionsTaken.add(ActionTakenValue.to(actionTakenBo));
303 		}
304        return actionsTaken;
305     }
306 	
307 	@Override
308 	public DocumentDetail getDocumentDetail(@WebParam(name = "documentId") String documentId) {
309 		if (StringUtils.isBlank(documentId)) {
310             throw new RiceIllegalArgumentException("documentId was null or blank");
311         }
312         if ( LOG.isDebugEnabled() ) {
313         	LOG.debug("Fetching DocumentDetail [id="+documentId+"]");
314         }
315         DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
316         if (document == null) {
317         	return null;
318         }
319         DocumentDetail documentDetailVO = DTOConverter.convertDocumentDetailNew(document);
320         if ( LOG.isDebugEnabled() ) {
321         	LOG.debug("Returning DocumentDetailVO [id=" + documentId + "]");
322         }
323         return documentDetailVO;
324 	}
325 
326     @Override
327     public List<org.kuali.rice.kew.api.document.DocumentStatusTransition> getDocumentStatusTransitionHistory(String documentId) {
328 		if (StringUtils.isBlank(documentId)) {
329             throw new RiceIllegalArgumentException("documentId was null or blank");
330         }
331         if ( LOG.isDebugEnabled() ) {
332             LOG.debug("Fetching document status transition history [id="+documentId+"]");
333         }
334         DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);;
335 
336         List<DocumentStatusTransition> list = document.getAppDocStatusHistory();
337 
338         List<org.kuali.rice.kew.api.document.DocumentStatusTransition> transitionHistory = new ArrayList<org.kuali.rice.kew.api.document.DocumentStatusTransition>(list.size());
339 
340         for (DocumentStatusTransition transition : list) {
341             transitionHistory.add(DocumentStatusTransition.to(transition));
342         }
343         return transitionHistory;
344     }
345 	
346 	@Override
347 	public List<RouteNodeInstance> getRouteNodeInstances(String documentId) {
348     	if (StringUtils.isBlank(documentId)) {
349             throw new RiceIllegalArgumentException("documentId was null or blank");
350         }
351 
352         if ( LOG.isDebugEnabled() ) {
353     		LOG.debug("Fetching RouteNodeInstances [documentId=" + documentId + "]");
354     	}
355     	DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
356     	if (documentBo == null) {
357     		return Collections.emptyList();
358     	}
359     	return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getFlattenedNodeInstances(documentBo, true));
360     }	
361 	
362 	@Override
363 	public List<RouteNodeInstance> getActiveRouteNodeInstances(String documentId) {
364 		if (StringUtils.isBlank(documentId)) {
365             throw new RiceIllegalArgumentException("documentId was null or blank");
366         }
367 
368         if ( LOG.isDebugEnabled() ) {
369     		LOG.debug("Fetching active RouteNodeInstances [documentId=" + documentId + "]");
370     	}
371         return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(documentId));
372 	}
373 
374     @Override
375     public List<RouteNodeInstance> getTerminalRouteNodeInstances(String documentId) {
376     	if (StringUtils.isBlank(documentId)) {
377             throw new RiceIllegalArgumentException("documentId was null or blank");
378         }
379 
380         if ( LOG.isDebugEnabled() ) {
381     		LOG.debug("Fetching terminal RouteNodeInstanceVOs [docId=" + documentId + "]");
382     	}
383         return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getTerminalNodeInstances(documentId));
384     }
385 
386     public List<RouteNodeInstance> getCurrentRouteNodeInstances(String documentId) {
387     	if (StringUtils.isBlank(documentId)) {
388             throw new RiceIllegalArgumentException("documentId was null or blank");
389         }
390 
391         if ( LOG.isDebugEnabled() ) {
392     		LOG.debug("Fetching current RouteNodeInstanceVOs [docId=" + documentId + "]");
393     	}
394     	return convertRouteNodeInstances(KEWServiceLocator.getRouteNodeService().getCurrentNodeInstances(documentId));
395     }
396     
397     public List<String> getActiveRouteNodeNames(String documentId) {
398     	if (StringUtils.isBlank(documentId)) {
399             throw new RiceIllegalArgumentException("documentId was null or blank");
400         }
401     	
402     	final List<String> nodes = KEWServiceLocator.getRouteNodeService().getActiveRouteNodeNames(documentId);
403     	return nodes != null ? Collections.unmodifiableList(nodes) : Collections.<String>emptyList();
404     }
405     
406     public List<String> getTerminalRouteNodeNames(String documentId) {
407     	if (StringUtils.isBlank(documentId)) {
408             throw new RiceIllegalArgumentException("documentId was null or blank");
409         }
410     	
411     	final List<String> nodes = KEWServiceLocator.getRouteNodeService().getTerminalRouteNodeNames(documentId);
412     	return nodes != null ? Collections.unmodifiableList(nodes) : Collections.<String>emptyList();
413     }
414 
415     public List<String> getCurrentRouteNodeNames(String documentId) {
416     	if (StringUtils.isBlank(documentId)) {
417             throw new RiceIllegalArgumentException("documentId was null or blank");
418         }
419     	
420     	final List<String> nodes = KEWServiceLocator.getRouteNodeService().getCurrentRouteNodeNames(documentId);
421     	return nodes != null ? Collections.unmodifiableList(nodes) : Collections.<String>emptyList();
422     }
423 
424 	private List<RouteNodeInstance> convertRouteNodeInstances(List<org.kuali.rice.kew.engine.node.RouteNodeInstance> routeNodeInstanceBos) {
425 		List<RouteNodeInstance> routeNodeInstances = new ArrayList<RouteNodeInstance>();
426         for (org.kuali.rice.kew.engine.node.RouteNodeInstance routeNodeInstanceBo : routeNodeInstanceBos) {
427         	routeNodeInstances.add(org.kuali.rice.kew.engine.node.RouteNodeInstance.to(routeNodeInstanceBo));
428         }
429         return Collections.unmodifiableList(routeNodeInstances);
430 	}
431 	
432 	@Override
433 	public List<String> getPreviousRouteNodeNames(String documentId) {
434 
435 		if (StringUtils.isBlank(documentId)) {
436             throw new RiceIllegalArgumentException("documentId was null or blank");
437         }
438         if ( LOG.isDebugEnabled() ) {
439 			LOG.debug("Fetching previous node names [documentId=" + documentId + "]");
440 		}
441         return new ArrayList<String>(KEWServiceLocator.getRouteNodeService().findPreviousNodeNames(documentId));
442 	}
443 
444     @Override
445     public List<String> getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(String actionRequestedCd, String documentId){
446     	if (StringUtils.isEmpty(actionRequestedCd)) {
447             throw new RiceIllegalArgumentException("actionRequestCd was blank or null");
448         }
449         if (StringUtils.isEmpty(documentId)) {
450             throw new RiceIllegalArgumentException("documentId was blank or null");
451         }
452         return KEWServiceLocator.getActionRequestService().
453     				getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(actionRequestedCd, documentId);
454     }
455 
456     @Override
457     public String getDocumentInitiatorPrincipalId(String documentId) {
458         if (StringUtils.isEmpty(documentId)) {
459             throw new RiceIllegalArgumentException("documentId was blank or null");
460         }
461 
462         DocumentRouteHeaderValue header = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId, false);
463         if ( header == null) {
464         	return null;
465         }
466     	return header.getInitiatorWorkflowId();
467     }
468 
469     @Override
470     public String getRoutedByPrincipalIdByDocumentId(String documentId) {
471         if (StringUtils.isEmpty(documentId)) {
472             throw new RiceIllegalArgumentException("documentId was blank or null");
473         }
474 
475         DocumentRouteHeaderValue header = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId, false);
476         if ( header == null) {
477         	return null;
478         }
479     	return header.getRoutedByUserWorkflowId();
480     }
481 
482 	@Override
483 	public DocumentLink addDocumentLink(DocumentLink documentLink) throws RiceIllegalArgumentException {
484 		if (documentLink == null) {
485 			throw new RiceIllegalArgumentException("documentLink was null");
486 		}
487 		if (documentLink.getId() != null) {
488 			throw new RiceIllegalArgumentException("the given documentLink already has an id, cannot add a document link with an existing id");
489 		}
490 		org.kuali.rice.kew.documentlink.DocumentLink documentLinkBo = org.kuali.rice.kew.documentlink.DocumentLink.from(documentLink);
491 		KEWServiceLocator.getDocumentLinkService().saveDocumentLink(documentLinkBo);
492 		return org.kuali.rice.kew.documentlink.DocumentLink.to(documentLinkBo);
493 	}
494 
495 	@Override
496 	public DocumentLink deleteDocumentLink(String documentLinkId) throws RiceIllegalArgumentException {
497 		if (StringUtils.isBlank(documentLinkId)) {
498 			throw new RiceIllegalArgumentException("documentLinkId was null or blank");
499 		}
500 		org.kuali.rice.kew.documentlink.DocumentLink documentLinkBo = KEWServiceLocator.getDocumentLinkService().getDocumentLink(Long.valueOf(documentLinkId));
501 		if (documentLinkBo == null) {
502 			throw new RiceIllegalStateException("Failed to locate document link with the given documentLinkId: " + documentLinkId);
503 		}
504 		KEWServiceLocator.getDocumentLinkService().deleteDocumentLink(documentLinkBo);
505 		return org.kuali.rice.kew.documentlink.DocumentLink.to(documentLinkBo);
506 	}
507 	    
508 	@Override
509 	public List<DocumentLink> deleteDocumentLinksByDocumentId(String originatingDocumentId) throws RiceIllegalArgumentException {
510 		if (StringUtils.isBlank(originatingDocumentId)) {
511 			throw new RiceIllegalArgumentException("originatingDocumentId was null or blank");
512 		}
513 		List<org.kuali.rice.kew.documentlink.DocumentLink> documentLinkBos = KEWServiceLocator.getDocumentLinkService().getLinkedDocumentsByDocId(originatingDocumentId);
514 		if (documentLinkBos == null || documentLinkBos.isEmpty()) {
515 			return Collections.emptyList();
516 		}
517 		List<DocumentLink> deletedDocumentLinks = new ArrayList<DocumentLink>();
518 		for (org.kuali.rice.kew.documentlink.DocumentLink documentLinkBo : documentLinkBos) {
519 			deletedDocumentLinks.add(org.kuali.rice.kew.documentlink.DocumentLink.to(documentLinkBo));
520 			KEWServiceLocator.getDocumentLinkService().deleteDocumentLink(documentLinkBo);
521 		}
522 		return Collections.unmodifiableList(deletedDocumentLinks);
523     }
524 	    
525 	@Override
526 	public List<DocumentLink> getOutgoingDocumentLinks(String originatingDocumentId) throws RiceIllegalArgumentException {
527 		if (StringUtils.isBlank(originatingDocumentId)) {
528 			throw new RiceIllegalArgumentException("originatingDocumentId was null or blank");
529 		}
530 		List<org.kuali.rice.kew.documentlink.DocumentLink> outgoingDocumentLinkBos = KEWServiceLocator.getDocumentLinkService().getLinkedDocumentsByDocId(originatingDocumentId);
531 		List<DocumentLink> outgoingDocumentLinks = new ArrayList<DocumentLink>();
532 		for (org.kuali.rice.kew.documentlink.DocumentLink outgoingDocumentLinkBo : outgoingDocumentLinkBos) {
533 			outgoingDocumentLinks.add(org.kuali.rice.kew.documentlink.DocumentLink.to(outgoingDocumentLinkBo));
534 		}
535 		return Collections.unmodifiableList(outgoingDocumentLinks);
536     }
537 	
538 	@Override
539 	public List<DocumentLink> getIncomingDocumentLinks(String destinationDocumentId) throws RiceIllegalArgumentException {
540 		if (StringUtils.isBlank(destinationDocumentId)) {
541 			throw new RiceIllegalArgumentException("destinationDocumentId was null or blank");
542 		}
543 		List<org.kuali.rice.kew.documentlink.DocumentLink> incomingDocumentLinkBos = KEWServiceLocator.getDocumentLinkService().getOutgoingLinkedDocumentsByDocId(destinationDocumentId);
544 		List<DocumentLink> incomingDocumentLinks = new ArrayList<DocumentLink>();
545 		for (org.kuali.rice.kew.documentlink.DocumentLink incomingDocumentLinkBo : incomingDocumentLinkBos) {
546 			incomingDocumentLinks.add(org.kuali.rice.kew.documentlink.DocumentLink.to(incomingDocumentLinkBo));
547 		}
548 		return Collections.unmodifiableList(incomingDocumentLinks);
549     }
550 	    
551 	@Override
552 	public DocumentLink getDocumentLink(String documentLinkId) throws RiceIllegalArgumentException {
553 		if (StringUtils.isBlank(documentLinkId)) {
554 			throw new RiceIllegalArgumentException("documentLinkId was null or blank");
555 		}
556 		org.kuali.rice.kew.documentlink.DocumentLink documentLinkBo = KEWServiceLocator.getDocumentLinkService().getDocumentLink(Long.valueOf(documentLinkId));
557 		return org.kuali.rice.kew.documentlink.DocumentLink.to(documentLinkBo);
558     }
559 	
560 }