001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.impl.document;
017
018import org.apache.commons.lang.StringUtils;
019import org.apache.log4j.Logger;
020import org.joda.time.DateTime;
021import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
022import org.kuali.rice.core.api.exception.RiceIllegalStateException;
023import org.kuali.rice.kew.actionrequest.ActionRequestValue;
024import org.kuali.rice.kew.actiontaken.ActionTakenValue;
025import org.kuali.rice.kew.api.action.ActionRequest;
026import org.kuali.rice.kew.api.action.ActionTaken;
027import org.kuali.rice.kew.api.doctype.RouteNode;
028import org.kuali.rice.kew.api.document.Document;
029import org.kuali.rice.kew.api.document.DocumentContent;
030import org.kuali.rice.kew.api.document.DocumentDetail;
031import org.kuali.rice.kew.api.document.DocumentLink;
032import org.kuali.rice.kew.api.document.DocumentStatus;
033import org.kuali.rice.kew.api.document.WorkflowDocumentService;
034import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
035import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
036import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
037import org.kuali.rice.kew.dto.DTOConverter;
038import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
039import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent;
040import org.kuali.rice.kew.routeheader.DocumentStatusTransition;
041import org.kuali.rice.kew.service.KEWServiceLocator;
042
043import javax.jws.WebParam;
044import java.math.BigDecimal;
045import java.sql.Timestamp;
046import java.util.ArrayList;
047import java.util.Collection;
048import java.util.Collections;
049import java.util.HashMap;
050import java.util.LinkedHashSet;
051import java.util.List;
052import java.util.Map;
053import java.util.Set;
054
055/**
056 * 
057 * @author Kuali Rice Team (rice.collab@kuali.org)
058 *
059 */
060public class WorkflowDocumentServiceImpl implements WorkflowDocumentService {
061
062        private static final Logger LOG = Logger.getLogger(WorkflowDocumentServiceImpl.class);
063        
064        @Override
065        public Document getDocument(String documentId) {
066                if (StringUtils.isBlank(documentId)) {
067                        throw new RiceIllegalArgumentException("documentId was blank or null");
068                }
069                DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
070                return DocumentRouteHeaderValue.to(documentBo);
071        }
072
073        @Override
074        public boolean doesDocumentExist(String documentId) {
075            if (StringUtils.isBlank(documentId)) {
076            throw new RiceIllegalArgumentException("documentId was blank or null");
077        }
078            DocumentRouteHeaderValue documentBo = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
079            return documentBo != null;
080        }
081
082    @Override
083    public DocumentDetail getDocumentDetailByAppId(String documentTypeName, String appId) {
084        if (StringUtils.isEmpty(documentTypeName)) {
085            throw new RiceIllegalArgumentException("documentTypeName was blank or null");
086        }
087        if (StringUtils.isEmpty(appId)) {
088            throw new RiceIllegalArgumentException("appId was blank or null");
089        }
090
091        Collection documentIds = KEWServiceLocator.getRouteHeaderService().findByDocTypeAndAppId(documentTypeName, appId);
092        if(documentIds==null||documentIds.isEmpty()){
093            throw new RiceIllegalStateException("No RouteHeader Ids found for documentTypName: " + documentTypeName + ", appId: " + appId);
094        }
095        if(documentIds.size()>1){
096            throw new RiceIllegalStateException("Multiple RouteHeader Ids found for documentTypName: " + documentTypeName + ", appId: " + appId);
097                }
098
099        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}