View Javadoc

1   /**
2    * Copyright 2005-2013 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.actionrequest;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.lang.builder.ToStringBuilder;
20  import org.apache.commons.lang.builder.ToStringStyle;
21  import org.hibernate.annotations.Fetch;
22  import org.hibernate.annotations.FetchMode;
23  import org.hibernate.annotations.GenericGenerator;
24  import org.hibernate.annotations.Parameter;
25  import org.joda.time.DateTime;
26  import org.kuali.rice.core.api.delegation.DelegationType;
27  import org.kuali.rice.core.api.util.RiceConstants;
28  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
29  import org.kuali.rice.kew.actionitem.ActionItem;
30  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
31  import org.kuali.rice.kew.api.action.ActionRequest;
32  import org.kuali.rice.kew.api.action.ActionRequestPolicy;
33  import org.kuali.rice.kew.api.action.ActionRequestStatus;
34  import org.kuali.rice.kew.api.action.ActionRequestType;
35  import org.kuali.rice.kew.api.action.ActionTaken;
36  import org.kuali.rice.kew.api.action.RecipientType;
37  import org.kuali.rice.kew.api.util.CodeTranslator;
38  import org.kuali.rice.kew.dto.DTOConverter.RouteNodeInstanceLoader;
39  import org.kuali.rice.kew.engine.CompatUtils;
40  import org.kuali.rice.kew.engine.node.RouteNode;
41  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
42  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
43  import org.kuali.rice.kew.rule.RuleBaseValues;
44  import org.kuali.rice.kew.rule.service.RuleServiceInternal;
45  import org.kuali.rice.kew.service.KEWServiceLocator;
46  import org.kuali.rice.kew.user.RoleRecipient;
47  import org.kuali.rice.kew.api.KewApiConstants;
48  import org.kuali.rice.kim.api.group.Group;
49  import org.kuali.rice.kim.api.identity.Person;
50  import org.kuali.rice.kim.api.identity.principal.Principal;
51  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
52  
53  import javax.persistence.CascadeType;
54  import javax.persistence.Column;
55  import javax.persistence.Entity;
56  import javax.persistence.FetchType;
57  import javax.persistence.GeneratedValue;
58  import javax.persistence.Id;
59  import javax.persistence.JoinColumn;
60  import javax.persistence.ManyToOne;
61  import javax.persistence.NamedQueries;
62  import javax.persistence.NamedQuery;
63  import javax.persistence.OneToMany;
64  import javax.persistence.Table;
65  import javax.persistence.Transient;
66  import java.io.Serializable;
67  import java.sql.Timestamp;
68  import java.util.ArrayList;
69  import java.util.Arrays;
70  import java.util.Iterator;
71  import java.util.List;
72  /**
73   * Bean mapped to DB. Represents ActionRequest to a workgroup, user or role.  Contains
74   * references to children/parent if a member of a graph
75   *
76   * @author Kuali Rice Team (rice.collab@kuali.org)
77   */
78  @Entity
79  @Table(name="KREW_ACTN_RQST_T")
80  //@Sequence(name="KREW_ACTN_RQST_S", property="actionRequestId")
81  @NamedQueries({
82    @NamedQuery(name="ActionRequestValue.FindByDocumentId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId"),
83    @NamedQuery(name="ActionRequestValue.GetUserRequestCount", query="select count(arv) from ActionRequestValue arv where arv.documentId = :documentId and arv.recipientTypeCd = :recipientTypeCd and arv.principalId = :principalId and arv.currentIndicator = :currentIndicator"),
84    @NamedQuery(name="ActionRequestValue.FindActivatedByGroup", query="select count(arv) from ActionRequestValue arv where arv.groupId = :groupId and arv.currentIndicator = :currentIndicator and arv.status = :status"),
85    @NamedQuery(name="ActionRequestValue.FindAllByDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator"),
86    @NamedQuery(name="ActionRequestValue.FindAllPendingByDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
87    @NamedQuery(name="ActionRequestValue.FindAllRootByDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null"),
88    @NamedQuery(name="ActionRequestValue.FindByStatusAndDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.status = :status"),
89    @NamedQuery(name="ActionRequestValue.FindPendingByActionRequestedAndDocId", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.actionRequested = :actionRequested and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
90    @NamedQuery(name="ActionRequestValue.FindPendingByDocIdAtOrBelowRouteLevel", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.status <> :status and arv.routeLevel <= :routeLevel"),
91    @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocIdAtOrBelowRouteLevel", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.status <> :status and routeLevel <= :routeLevel"),
92    @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocIdAtRouteLevel", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.status <> :status and routeLevel = :routeLevel"),
93    @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocIdAtRouteNode", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.nodeInstance.routeNodeInstanceId = :routeNodeInstanceId and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
94    @NamedQuery(name="ActionRequestValue.FindPendingRootRequestsByDocumentType", query="select arv from ActionRequestValue arv where arv.documentId in (select drhv.documentId from DocumentRouteHeaderValue drhv where drhv.documentTypeId = :documentTypeId) and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and (arv.status = :actionRequestStatus1 or arv.status = :actionRequestStatus2)"),
95    @NamedQuery(name="ActionRequestValue.FindRootRequestsByDocIdAtRouteNode", query="select arv from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.parentActionRequest is null and arv.nodeInstance.routeNodeInstanceId = :routeNodeInstanceId"),
96    @NamedQuery(name="ActionRequestValue.GetRequestGroupIds", query="select arv.groupId from ActionRequestValue arv where arv.documentId = :documentId and arv.currentIndicator = :currentIndicator and arv.recipientTypeCd = :recipientTypeCd"),
97    @NamedQuery(name="ActionRequestValue.FindByStatusAndGroupId", query="select arv from ActionRequestValue arv where arv.groupId = :groupId and arv.currentIndicator = :currentIndicator and arv.status = :status")
98  })
99  public class ActionRequestValue implements Serializable {
100 
101 	private static final long serialVersionUID = 8781414791855848385L;
102 
103 	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ActionRequestValue.class);
104 
105     private static final String ACTION_CODE_RANK = "FKACB";//B is a hack for allowing blanket approves to count for approve and complete requests in findPreviousAction in ActionTakenService this is a hack and accounts for the -3 on compareActionCode
106     private static final String RECIPIENT_TYPE_RANK = "RWU";
107     private static final List DELEGATION_TYPE_RANK = Arrays.asList(new Object[]{DelegationType.SECONDARY, DelegationType.PRIMARY, null});
108 
109     @Id
110     @GeneratedValue(generator="KREW_ACTN_RQST_S")
111 	@GenericGenerator(name="KREW_ACTN_RQST_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
112 			@Parameter(name="sequence_name",value="KREW_ACTN_RQST_S"),
113 			@Parameter(name="value_column",value="id")
114 	})
115 	@Column(name="ACTN_RQST_ID")
116 	private String actionRequestId;
117     @Column(name="ACTN_RQST_CD")
118 	private String actionRequested;
119     @Column(name="DOC_HDR_ID")
120 	private String documentId;
121     @Column(name="STAT_CD")
122 	private String status;
123     @Column(name="RSP_ID")
124 	private String responsibilityId;
125     @Column(name="GRP_ID")
126 	private String groupId;
127     @Column(name="RECIP_TYP_CD")
128 	private String recipientTypeCd;
129     @Column(name="PRIO_NBR")
130 	private Integer priority;
131     @Column(name="RTE_LVL_NBR")
132 	private Integer routeLevel;
133     @Column(name="ACTN_TKN_ID", insertable=false, updatable=false)
134 	private String actionTakenId;
135     @Column(name="DOC_VER_NBR")
136     private Integer docVersion = 1;
137 	@Column(name="CRTE_DT")
138 	private java.sql.Timestamp createDate;
139     @Column(name="RSP_DESC_TXT")
140 	private String responsibilityDesc;
141     @Column(name="ACTN_RQST_ANNOTN_TXT")
142 	private String annotation;
143     @Column(name="VER_NBR")
144 	private Integer jrfVerNbr;
145     @Column(name="PRNCPL_ID")
146 	private String principalId;
147     @Column(name="FRC_ACTN")
148 	private Boolean forceAction;
149     @Column(name="PARNT_ID", insertable=false, updatable=false)
150 	private String parentActionRequestId;
151     @Column(name="QUAL_ROLE_NM")
152 	private String qualifiedRoleName;
153     @Column(name="ROLE_NM")
154 	private String roleName;
155     @Column(name="QUAL_ROLE_NM_LBL_TXT")
156 	private String qualifiedRoleNameLabel;
157     @Transient
158     private String displayStatus;
159     @Column(name="RULE_ID")
160 	private String ruleBaseValuesId;
161 
162     @Column(name="DLGN_TYP")
163     private String delegationTypeCode;
164     @Column(name="APPR_PLCY")
165 	private String approvePolicy;
166 
167     @ManyToOne(fetch=FetchType.EAGER)
168 	@JoinColumn(name="PARNT_ID")
169 	private ActionRequestValue parentActionRequest;
170     @Fetch(value = FetchMode.SELECT)
171     @OneToMany(mappedBy="parentActionRequest",cascade={CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER)
172     private List<ActionRequestValue> childrenRequests = new ArrayList<ActionRequestValue>();
173     @ManyToOne(fetch=FetchType.EAGER)
174 	@JoinColumn(name="ACTN_TKN_ID")
175 	private ActionTakenValue actionTaken;
176     //@OneToMany(fetch=FetchType.LAZY,mappedBy="actionRequestId")
177     //private List<ActionItem> actionItems = new ArrayList<ActionItem>();
178     @Column(name="CUR_IND")
179     private Boolean currentIndicator = true;
180     @Transient
181     private String createDateString;
182 
183     /* New Workflow 2.1 Field */
184     // The node instance at which this request was generated
185     @ManyToOne(fetch=FetchType.EAGER)
186 	@JoinColumn(name="RTE_NODE_INSTN_ID")
187 	private RouteNodeInstance nodeInstance;
188 
189     @Column(name="RQST_LBL")
190     private String requestLabel;
191     
192     @Transient
193     private boolean resolveResponsibility = true;
194     @Transient
195     private DocumentRouteHeaderValue routeHeader;
196     @Transient
197     private List<ActionItem> simulatedActionItems;
198     
199     public ActionRequestValue() {
200         createDate = new Timestamp(System.currentTimeMillis());
201     }
202     
203     //@PrePersist
204     public void beforeInsert(){
205     	OrmUtils.populateAutoIncValue(this, KEWServiceLocator.getEntityManagerFactory().createEntityManager());
206     }
207    
208     public Group getGroup() {
209         if (getGroupId() == null) {
210             LOG.error("Attempting to get a group with a blank group id");
211             return null;
212         }
213         return KimApiServiceLocator.getGroupService().getGroup(getGroupId());
214     }
215 
216     public String getRouteLevelName() {
217         // this is for backward compatibility of requests which have not been converted
218         if (CompatUtils.isRouteLevelRequest(this)) {
219             int routeLevelInt = getRouteLevel();
220             if (routeLevelInt == KewApiConstants.EXCEPTION_ROUTE_LEVEL) {
221                 return "Exception";
222             }
223 
224             List<RouteNode> routeLevelNodes = CompatUtils.getRouteLevelCompatibleNodeList(KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId).getDocumentType());
225             if (!(routeLevelInt < routeLevelNodes.size())) {
226                 return "Not Found";
227             }
228             return ((RouteNode)routeLevelNodes.get(routeLevelInt)).getRouteNodeName();
229         } else {
230             return (nodeInstance == null ? "Exception" : nodeInstance.getName());
231         }
232     }
233 
234     public boolean isUserRequest() {
235         return principalId != null;
236     }
237 
238     public Principal getPrincipal() {
239     	if (getPrincipalId() == null) {
240     		return null;
241     	}
242     	return KEWServiceLocator.getIdentityHelperService().getPrincipal(getPrincipalId());
243     }
244     
245     public Person getPerson() {
246     	if (getPrincipalId() == null) {
247     		return null;
248     	}
249     	return KimApiServiceLocator.getPersonService().getPerson(getPrincipalId());
250     }
251 
252     public String getDisplayName() {
253     	if (isUserRequest()) {
254             Person person = getPerson();
255             if ( person != null ) {
256     	        return person.getName();
257             }
258     	} else if (isGroupRequest()) {
259             Group group = getGroup();
260             if ( group != null ) {
261     		    return group.getName();
262             } else {
263                 return getGroupId();
264             }
265     	} else if (isRoleRequest()) {
266     		return getRoleName();
267     	}
268     	return "";
269     }
270 
271     public Recipient getRecipient() {
272         if (getPrincipalId() != null) {
273             return new KimPrincipalRecipient(getPrincipal());
274         } else if (getGroupId() != null){
275             return new KimGroupRecipient(getGroup());
276         } else {
277         	return new RoleRecipient(this.getRoleName());
278         }
279     }
280 
281     public boolean isPending() {
282         return ActionRequestStatus.INITIALIZED.getCode().equals(getStatus()) || ActionRequestStatus.ACTIVATED.getCode().equals(getStatus());
283     }
284 
285     public String getStatusLabel() {
286         return CodeTranslator.getActionRequestStatusLabel(getStatus());
287     }
288 
289     public String getActionRequestedLabel() {
290     	if (StringUtils.isNotBlank(getRequestLabel())) {
291     		return getRequestLabel();
292     	}
293     	return CodeTranslator.getActionRequestLabel(getActionRequested());
294     }
295 
296     /**
297      * @return Returns the actionTaken.
298      */
299     public ActionTakenValue getActionTaken() {
300         return actionTaken;
301     }
302 
303     /**
304      * @param actionTaken
305      *            The actionTaken to set.
306      */
307     public void setActionTaken(ActionTakenValue actionTaken) {
308         this.actionTaken = actionTaken;
309     }
310 
311     /**
312      * @return Returns the actionRequested.
313      */
314     public String getActionRequested() {
315         return actionRequested;
316     }
317 
318     /**
319      * @param actionRequested
320      *            The actionRequested to set.
321      */
322     public void setActionRequested(String actionRequested) {
323         this.actionRequested = actionRequested;
324     }
325 
326     /**
327      * @return Returns the actionRequestId.
328      */
329     public String getActionRequestId() {
330         return actionRequestId;
331     }
332 
333     /**
334      * @param actionRequestId
335      *            The actionRequestId to set.
336      */
337     public void setActionRequestId(String actionRequestId) {
338         this.actionRequestId = actionRequestId;
339     }
340 
341     /**
342      * @return Returns the actionTakenId.
343      */
344     public String getActionTakenId() {
345         return actionTakenId;
346     }
347 
348     /**
349      * @param actionTakenId
350      *            The actionTakenId to set.
351      */
352     public void setActionTakenId(String actionTakenId) {
353         this.actionTakenId = actionTakenId;
354     }
355 
356     /**
357      * @return Returns the annotation.
358      */
359     public String getAnnotation() {
360         return annotation;
361     }
362 
363     /**
364      * @param annotation
365      *            The annotation to set.
366      */
367     public void setAnnotation(String annotation) {
368         this.annotation = annotation;
369     }
370 
371     /**
372      * @return Returns the createDate.
373      */
374     public java.sql.Timestamp getCreateDate() {
375         return createDate;
376     }
377 
378     /**
379      * @param createDate
380      *            The createDate to set.
381      */
382     public void setCreateDate(java.sql.Timestamp createDate) {
383         this.createDate = createDate;
384     }
385 
386     /**
387      * @return Returns the docVersion.
388      */
389     public Integer getDocVersion() {
390         return docVersion;
391     }
392 
393     /**
394      * @param docVersion
395      *            The docVersion to set.
396      */
397     public void setDocVersion(Integer docVersion) {
398         this.docVersion = docVersion;
399     }
400 
401     public String getPrincipalId() {
402         return principalId;
403     }
404 
405     public void setPrincipalId(String principalId) {
406         this.principalId = principalId;
407     }
408     
409     /**
410      * @return Returns the forceAction.
411      */
412     public Boolean getForceAction() {
413         return forceAction;
414     }
415 
416     /**
417      * @param forceAction
418      *            The forceAction to set.
419      */
420     public void setForceAction(Boolean forceAction) {
421         this.forceAction = forceAction;
422     }
423 
424     /**
425      * @return Returns the jrfVerNbr.
426      */
427     public Integer getJrfVerNbr() {
428         return jrfVerNbr;
429     }
430 
431     /**
432      * @param jrfVerNbr
433      *            The jrfVerNbr to set.
434      */
435     public void setJrfVerNbr(Integer jrfVerNbr) {
436         this.jrfVerNbr = jrfVerNbr;
437     }
438 
439     /**
440      * @return Returns the priority.
441      */
442     public Integer getPriority() {
443         return priority;
444     }
445 
446     /**
447      * @param priority
448      *            The priority to set.
449      */
450     public void setPriority(Integer priority) {
451         this.priority = priority;
452     }
453 
454     /**
455      * @return Returns the recipientTypeCd.
456      */
457     public String getRecipientTypeCd() {
458         return recipientTypeCd;
459     }
460 
461     /**
462      * @param recipientTypeCd
463      *            The recipientTypeCd to set.
464      */
465     public void setRecipientTypeCd(String recipientTypeCd) {
466         this.recipientTypeCd = recipientTypeCd;
467     }
468 
469     /**
470      * @return Returns the responsibilityDesc.
471      */
472     public String getResponsibilityDesc() {
473         return responsibilityDesc;
474     }
475 
476     /**
477      * @param responsibilityDesc
478      *            The responsibilityDesc to set.
479      */
480     public void setResponsibilityDesc(String responsibilityDesc) {
481         this.responsibilityDesc = responsibilityDesc;
482     }
483 
484     /**
485      * @return Returns the responsibilityId.
486      */
487     public String getResponsibilityId() {
488         return responsibilityId;
489     }
490 
491     /**
492      * @param responsibilityId
493      *            The responsibilityId to set.
494      */
495     public void setResponsibilityId(String responsibilityId) {
496         this.responsibilityId = responsibilityId;
497     }
498 
499     /**
500      * @return Returns the documentId.
501      */
502     public String getDocumentId() {
503         return documentId;
504     }
505 
506     public void setDocumentId(String documentId) {
507         this.documentId = documentId;
508     }
509 
510     public Integer getRouteLevel() {
511         return routeLevel;
512     }
513 
514     public void setRouteLevel(Integer routeLevel) {
515         this.routeLevel = routeLevel;
516     }
517 
518     public String getStatus() {
519         return status;
520     }
521 
522     public void setStatus(String status) {
523         this.status = status;
524     }
525 
526     public String getGroupId() {
527         return groupId;
528     }
529 
530     public void setGroupId(String groupId) {
531         this.groupId = groupId;
532     }
533 
534     public boolean isInitialized() {
535         return ActionRequestStatus.INITIALIZED.getCode().equals(getStatus());
536     }
537 
538     public boolean isActive() {
539         return ActionRequestStatus.ACTIVATED.getCode().equals(getStatus());
540     }
541 
542     public boolean isApproveOrCompleteRequest() {
543         return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested()) || KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
544     }
545 
546     public boolean isDone() {
547         return ActionRequestStatus.DONE.getCode().equals(getStatus());
548     }
549 
550     public boolean isReviewerUser() {
551         return RecipientType.PRINCIPAL.getCode().equals(getRecipientTypeCd());
552     }
553 
554     /**
555      * Determines whether the specified principalId is in the recipient graph of this action request
556      * @param principalId the principal id to check
557      * @return whether the specified principalId is in the recipient graph of this action request
558      */
559     public boolean isRecipientRoutedRequest(String principalId) {
560     	//before altering this method it is used in checkRouteLogAuthentication
561     	//don't break that method
562     	if (principalId == null || "".equals(principalId)) {
563     		return false;
564     	}
565 
566     	boolean isRecipientInGraph = false;
567     	if (isReviewerUser()) {
568     			isRecipientInGraph = getPrincipalId().equals(principalId);
569     	} else if (isGroupRequest()) {
570     		Group group = getGroup();
571 			if (group == null){
572 				LOG.error("Was unable to retrieve workgroup " + getGroupId());
573 			}
574     		isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, group.getId());
575     	}
576 
577 
578         for (ActionRequestValue childRequest : getChildrenRequests())
579         {
580             isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(principalId);
581         }
582 
583     	return isRecipientInGraph;
584     }
585 
586     public boolean isRecipientRoutedRequest(Recipient recipient) {
587     	//before altering this method it is used in checkRouteLogAuthentication
588     	//don't break that method
589     	if (recipient == null) {
590     		return false;
591     	}
592 
593     	boolean isRecipientInGraph = false;
594     	if (isReviewerUser()) {
595     		if (recipient instanceof KimPrincipalRecipient) {
596     			isRecipientInGraph = getPrincipalId().equals(((KimPrincipalRecipient) recipient).getPrincipalId());
597     		} else if (recipient instanceof KimGroupRecipient){
598     			isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(getPrincipalId(), ((KimGroupRecipient)recipient).getGroup().getId());
599     		}
600 
601     	} else if (isGroupRequest()) {
602     		Group group = getGroup();
603 			if (group == null){
604 				LOG.error("Was unable to retrieve workgroup " + getGroupId());
605 			}
606     		if (recipient instanceof KimPrincipalRecipient) {
607     			KimPrincipalRecipient principalRecipient = (KimPrincipalRecipient)recipient;
608     			isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalRecipient.getPrincipalId(), group.getId());
609     		} else if (recipient instanceof KimGroupRecipient) {
610     			isRecipientInGraph = ((KimGroupRecipient) recipient).getGroup().getId().equals(group.getId());
611     		}
612     	}
613 
614 
615         for (ActionRequestValue childRequest : getChildrenRequests())
616         {
617             isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(recipient);
618         }
619 
620     	return isRecipientInGraph;
621     }
622 
623     public boolean isGroupRequest(){
624     	return RecipientType.GROUP.getCode().equals(getRecipientTypeCd());
625     }
626 
627     public boolean isRoleRequest() {
628         return RecipientType.ROLE.getCode().equals(getRecipientTypeCd());
629     }
630 
631     public boolean isAcknowledgeRequest() {
632         return KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(getActionRequested());
633     }
634 
635     public boolean isApproveRequest() {
636         return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested());
637     }
638 
639     public boolean isCompleteRequst() {
640         return KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
641     }
642 
643     public boolean isFYIRequest() {
644         return KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(getActionRequested());
645     }
646 
647     /**
648      * Allows comparison of action requests to see which is greater responsibility. -1 : indicates code 1 is lesser responsibility than code 2 0 : indicates the same responsibility 1 : indicates code1 is greater responsibility than code 2 The priority of action requests is as follows: fyi < acknowledge < (approve == complete)
649      *
650      * @param code1
651      * @param code2
652      * @param completeAndApproveTheSame
653      * @return -1 if less than, 0 if equal, 1 if greater than
654      */
655     public static int compareActionCode(String code1, String code2, boolean completeAndApproveTheSame) {
656     	int cutoff = Integer.MAX_VALUE;
657     	if (completeAndApproveTheSame) {
658     		// hacked so that APPROVE and COMPLETE are equal
659     		cutoff = ACTION_CODE_RANK.length() - 3;
660     	}
661         Integer code1Index = Math.min(ACTION_CODE_RANK.indexOf(code1), cutoff);
662         Integer code2Index = Math.min(ACTION_CODE_RANK.indexOf(code2), cutoff);
663         return code1Index.compareTo(code2Index);
664     }
665 
666     /**
667      * Allows comparison of action requests to see which is greater responsibility. -1 : indicates type 1 is lesser responsibility than type 2 0 : indicates the same responsibility 1 : indicates type1 is greater responsibility than type 2
668      *
669      * @param type1
670      * @param type2
671      * @return -1 if less than, 0 if equal, 1 if greater than
672      */
673     public static int compareRecipientType(String type1, String type2) {
674         Integer type1Index = RECIPIENT_TYPE_RANK.indexOf(type1);
675         Integer type2Index = RECIPIENT_TYPE_RANK.indexOf(type2);
676         return type1Index.compareTo(type2Index);
677     }
678 
679     public static int compareDelegationType(DelegationType type1, DelegationType type2) {
680     	Integer type1Index = DELEGATION_TYPE_RANK.indexOf(type1);
681         Integer type2Index = DELEGATION_TYPE_RANK.indexOf(type2);
682         return type1Index.compareTo(type2Index);
683     }
684 
685     public List<ActionItem> getActionItems() {
686     	if (this.simulatedActionItems == null || this.simulatedActionItems.isEmpty()) {
687     		return (List<ActionItem>) KEWServiceLocator.getActionListService().findByActionRequestId(actionRequestId);
688     	} else {
689     		return this.simulatedActionItems;
690     	}
691     }
692 
693     public List<ActionItem> getSimulatedActionItems() {
694     	if (this.simulatedActionItems == null) {
695     		this.simulatedActionItems = new ArrayList<ActionItem>();
696     	}
697 		return this.simulatedActionItems;
698 	}
699 
700 	public void setSimulatedActionItems(List<ActionItem> simulatedActionItems) {
701 		this.simulatedActionItems = simulatedActionItems;
702 	}
703 
704 	public Boolean getCurrentIndicator() {
705         return currentIndicator;
706     }
707 
708     public void setCurrentIndicator(Boolean currentIndicator) {
709         this.currentIndicator = currentIndicator;
710     }
711 
712     public String getParentActionRequestId() {
713         return parentActionRequestId;
714     }
715 
716     public void setParentActionRequestId(String parentActionRequestId) {
717         this.parentActionRequestId = parentActionRequestId;
718     }
719 
720     public ActionRequestValue getParentActionRequest() {
721         return parentActionRequest;
722     }
723 
724     public void setParentActionRequest(ActionRequestValue parentActionRequest) {
725         this.parentActionRequest = parentActionRequest;
726     }
727 
728     public List<ActionRequestValue> getChildrenRequests() {
729         return childrenRequests;
730     }
731 
732     public void setChildrenRequests(List<ActionRequestValue> childrenRequests) {
733         this.childrenRequests = childrenRequests;
734     }
735 
736     public String getQualifiedRoleName() {
737         return qualifiedRoleName;
738     }
739 
740     public void setQualifiedRoleName(String roleName) {
741         this.qualifiedRoleName = roleName;
742     }
743 
744     public DelegationType getDelegationType() {
745         return DelegationType.fromCode(delegationTypeCode);
746     }
747 
748     public void setDelegationType(DelegationType delegationPolicy) {
749         this.delegationTypeCode = delegationPolicy == null ? null : delegationPolicy.getCode();
750     }
751 
752 
753     public String getDelegationTypeCode() {
754         return delegationTypeCode;
755     }
756 
757     public void setDelegationTypeCode(String delegationTypeCode) {
758         this.delegationTypeCode = delegationTypeCode;
759     }
760 
761     public String getRoleName() {
762         return roleName;
763     }
764 
765     public void setRoleName(String roleName) {
766         this.roleName = roleName;
767     }
768 
769     public String getApprovePolicy() {
770         return approvePolicy;
771     }
772 
773     public void setApprovePolicy(String requestType) {
774         this.approvePolicy = requestType;
775     }
776 
777     public boolean getHasApprovePolicy() {
778         return getApprovePolicy() != null;
779     }
780 
781     public boolean isDeactivated() {
782         return ActionRequestStatus.DONE.getCode().equals(getStatus());
783     }
784 
785     public boolean hasParent() {
786         return getParentActionRequest() != null;
787     }
788 
789     public boolean hasChild(ActionRequestValue actionRequest) {
790         if (actionRequest == null)
791             return false;
792         String actionRequestId = actionRequest.getActionRequestId();
793         for (Iterator<ActionRequestValue> iter = getChildrenRequests().iterator(); iter.hasNext();) {
794             ActionRequestValue childRequest = iter.next();
795             if (childRequest.equals(actionRequest) || (actionRequestId != null && actionRequestId.equals(childRequest.getActionRequestId()))) {
796                 return true;
797             }
798         }
799         return false;
800     }
801 
802     public String getDisplayStatus() {
803         return displayStatus;
804     }
805 
806     public void setDisplayStatus(String displayStatus) {
807         this.displayStatus = displayStatus;
808     }
809 
810     public String getQualifiedRoleNameLabel() {
811         return qualifiedRoleNameLabel;
812     }
813 
814     public void setQualifiedRoleNameLabel(String qualifiedRoleNameLabel) {
815         this.qualifiedRoleNameLabel = qualifiedRoleNameLabel;
816     }
817 
818     public String getCreateDateString() {
819         if (createDateString == null || createDateString.trim().equals("")) {
820             return RiceConstants.getDefaultDateFormat().format(getCreateDate());
821         } else {
822             return createDateString;
823         }
824     }
825 
826     public void setCreateDateString(String createDateString) {
827         this.createDateString = createDateString;
828     }
829 
830     public RouteNodeInstance getNodeInstance() {
831 		return nodeInstance;
832 	}
833 
834     public String getPotentialNodeName() {
835         return (getNodeInstance() == null ? "" : getNodeInstance().getName());
836     }
837 
838 	public void setNodeInstance(RouteNodeInstance nodeInstance) {
839 		this.nodeInstance = nodeInstance;
840 	}
841 
842 	public String getRecipientTypeLabel() {
843 		return RecipientType.fromCode(getRecipientTypeCd()).getLabel();
844     }
845 
846     public RuleBaseValues getRuleBaseValues(){
847         if(ruleBaseValuesId != null){
848             return getRuleService().findRuleBaseValuesById(ruleBaseValuesId);
849         }
850         return null;
851     }
852     public String getRuleBaseValuesId() {
853         return ruleBaseValuesId;
854     }
855 
856     public void setRuleBaseValuesId(String ruleBaseValuesId) {
857         this.ruleBaseValuesId = ruleBaseValuesId;
858     }
859     
860 	private RuleServiceInternal getRuleService() {
861         return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
862     }
863 
864     public boolean isPrimaryDelegator() {
865         boolean primaryDelegator = false;
866         for (Iterator<ActionRequestValue> iter = childrenRequests.iterator(); iter.hasNext();) {
867             ActionRequestValue childRequest = iter.next();
868             primaryDelegator = DelegationType.PRIMARY.equals(childRequest.getDelegationType()) || primaryDelegator;
869         }
870         return primaryDelegator;
871     }
872 
873     /**
874      * Used to get primary delegate names on route log in the 'Requested Of' section so primary delegate requests
875      * list the delegate and not the delegator as having the request 'IN ACTION LIST'.  This method doesn't recurse
876      * and therefore assume an AR structure.
877      *
878      * @return primary delgate requests
879      */
880     public List<ActionRequestValue> getPrimaryDelegateRequests() {
881         List<ActionRequestValue> primaryDelegateRequests = new ArrayList<ActionRequestValue>();
882         for (ActionRequestValue childRequest : childrenRequests)
883         {
884             if (DelegationType.PRIMARY.equals(childRequest.getDelegationType()))
885             {
886                 if (childRequest.isRoleRequest())
887                 {
888                     for (ActionRequestValue actionRequestValue : childRequest.getChildrenRequests())
889                     {
890                         primaryDelegateRequests.add(actionRequestValue);
891                     }
892                 } else
893                 {
894                 	primaryDelegateRequests.add(childRequest);
895                 }
896             }
897         }
898         return primaryDelegateRequests;
899     }
900 
901     public boolean isAdHocRequest() {                                          
902     	return KewApiConstants.ADHOC_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
903     }
904 
905     public boolean isGeneratedRequest() {
906     	return KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(getResponsibilityId());
907     }
908 
909     public boolean isExceptionRequest() {
910     	return KewApiConstants.EXCEPTION_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
911     }
912 
913     public boolean isRouteModuleRequest() {
914     	// FIXME: KULRICE-5201 switched rsp_id to a varchar, so the comparison below is no longer valid
915 //    	return getResponsibilityId() > 0;
916     	// TODO: KULRICE-5329 Verify that this code below makes sense 
917     	return getResponsibilityId() != null && !KewApiConstants.SPECIAL_RESPONSIBILITY_ID_SET.contains(getResponsibilityId());
918     }
919 
920     public String toString() {
921         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
922             .append("actionRequestId", actionRequestId)
923             .append("actionRequested", actionRequested)
924             .append("documentId", documentId)
925             .append("status", status)
926             .append("responsibilityId", responsibilityId)
927             .append("groupId", groupId)
928             .append("recipientTypeCd", recipientTypeCd)
929             .append("priority", priority)
930             .append("routeLevel", routeLevel)
931             .append("actionTakenId", actionTakenId)
932             .append("docVersion", docVersion)
933             .append("createDate", createDate)
934             .append("responsibilityDesc", responsibilityDesc)
935             .append("annotation", annotation)
936             .append("jrfVerNbr", jrfVerNbr)
937             .append("principalId", principalId)
938             .append("forceAction", forceAction)
939             .append("parentActionRequestId", parentActionRequestId)
940             .append("qualifiedRoleName", qualifiedRoleName)
941             .append("roleName", roleName)
942             .append("qualifiedRoleNameLabel", qualifiedRoleNameLabel)
943             .append("displayStatus", displayStatus)
944             .append("ruleBaseValuesId", ruleBaseValuesId)
945             .append("delegationType", delegationTypeCode)
946             .append("approvePolicy", approvePolicy)
947             .append("actionTaken", actionTaken)
948             .append("currentIndicator", currentIndicator)
949             .append("createDateString", createDateString)
950             .append("nodeInstance", nodeInstance).toString();
951     }
952 
953 	public String getRequestLabel() {
954 		return this.requestLabel;
955 	}
956 
957 	public void setRequestLabel(String requestLabel) {
958 		this.requestLabel = requestLabel;
959 	}
960 
961     public String getGroupName() {
962         return KimApiServiceLocator.getGroupService().getGroup(this.groupId).getName();
963     }
964 
965 	/**
966 	 * @return the resolveResponsibility
967 	 */
968 	public boolean getResolveResponsibility() {
969 		return this.resolveResponsibility;
970 	}
971 
972 	/**
973 	 * @param resolveResponsibility the resolveResponsibility to set
974 	 */
975 	public void setResolveResponsibility(boolean resolveResponsibility) {
976 		this.resolveResponsibility = resolveResponsibility;
977 	}
978 
979 	public DocumentRouteHeaderValue getRouteHeader() {
980 		if (this.routeHeader == null && this.documentId != null) {
981 			this.routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(this.documentId);
982 		}
983 		return this.routeHeader;
984 	}
985 
986 	public void setRouteHeader(DocumentRouteHeaderValue routeHeader) {
987 		this.routeHeader = routeHeader;
988 	}
989 	
990 	public static ActionRequest to(ActionRequestValue actionRequestBo) {
991 		if (actionRequestBo == null) {
992 			return null;
993 		}
994 		return createActionRequestBuilder(actionRequestBo).build();
995 	}
996 	
997 	private static ActionRequest.Builder createActionRequestBuilder(ActionRequestValue actionRequestBo) {
998 		ActionRequest.Builder builder = ActionRequest.Builder.create(actionRequestBo.getActionRequestId(),
999 				ActionRequestType.fromCode(actionRequestBo.getActionRequested()),
1000 				ActionRequestStatus.fromCode(actionRequestBo.getStatus()),
1001 				actionRequestBo.getResponsibilityId(),
1002 				actionRequestBo.getDocumentId(),
1003 				RecipientType.fromCode(actionRequestBo.getRecipientTypeCd()));
1004 		if (actionRequestBo.getActionTaken() != null) {
1005 			builder.setActionTaken(ActionTaken.Builder.create(ActionTakenValue.to(actionRequestBo.getActionTaken())));
1006 		}
1007 		builder.setAnnotation(actionRequestBo.getAnnotation());
1008 		builder.setCurrent(actionRequestBo.getCurrentIndicator().booleanValue());
1009 		builder.setDateCreated(new DateTime(actionRequestBo.getCreateDate().getTime()));
1010 		if (actionRequestBo.getDelegationType() != null) {
1011 			builder.setDelegationType(actionRequestBo.getDelegationType());
1012 		}
1013 		builder.setForceAction(actionRequestBo.getForceAction().booleanValue());
1014 		builder.setGroupId(actionRequestBo.getGroupId());
1015 		builder.setNodeName(actionRequestBo.getPotentialNodeName());
1016 		if (actionRequestBo.getParentActionRequestId() != null) {
1017 			builder.setParentActionRequestId(actionRequestBo.getParentActionRequestId());
1018 		}
1019 		builder.setPrincipalId(actionRequestBo.getPrincipalId());
1020 		if (actionRequestBo.getPriority() == null) {
1021 			builder.setPriority(KewApiConstants.ACTION_REQUEST_DEFAULT_PRIORITY);
1022 		} else {
1023             builder.setPriority(actionRequestBo.getPriority().intValue());
1024         }
1025         if (actionRequestBo.getRouteLevel() == null ) {
1026             builder.setRouteLevel(0);
1027         } else {
1028             builder.setRouteLevel(actionRequestBo.getRouteLevel().intValue());
1029         }
1030 		builder.setQualifiedRoleName(actionRequestBo.getQualifiedRoleName());
1031 		builder.setQualifiedRoleNameLabel(actionRequestBo.getQualifiedRoleNameLabel());
1032 		builder.setRequestLabel(actionRequestBo.getRequestLabel());
1033 		if (!StringUtils.isBlank(actionRequestBo.getApprovePolicy())) {
1034 			builder.setRequestPolicy(ActionRequestPolicy.fromCode(actionRequestBo.getApprovePolicy()));
1035 		}
1036 		builder.setResponsibilityDescription(actionRequestBo.getResponsibilityDesc());
1037 		builder.setRoleName(actionRequestBo.getRoleName());
1038 		if (actionRequestBo.getNodeInstance() != null) {
1039 			builder.setRouteNodeInstanceId(actionRequestBo.getNodeInstance().getRouteNodeInstanceId());
1040 		}
1041 		
1042 		List<ActionRequest.Builder> childRequests = new ArrayList<ActionRequest.Builder>();
1043 		if (actionRequestBo.getChildrenRequests() != null) {
1044 			for (ActionRequestValue childActionRequestBo : actionRequestBo.getChildrenRequests()) {
1045 				childRequests.add(createActionRequestBuilder(childActionRequestBo));
1046 			}
1047 		}
1048 		builder.setChildRequests(childRequests);
1049 		return builder;
1050 	}
1051 	
1052     /**
1053      * TODO - this javadoc copied from DTOConverter, needs to be updated!
1054      * 
1055      * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1056      * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1057      * references in the conversion. NOTE: This method's primary purpose is to convert ActionRequestVOs returned from a
1058      * RouteModule. Incidentally, the DTO's returned from the route module will be lacking some information (like the node
1059      * instance) so no attempts are made to convert this data since further initialization is handled by a higher level
1060      * component (namely ActionRequestService.initializeActionRequestGraph).
1061      */
1062     public static ActionRequestValue from(ActionRequest actionRequest) {
1063         return ActionRequestValue.from(actionRequest, null);
1064     }
1065     
1066     /**
1067      * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1068      * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1069      * references in the conversion. 
1070      * @param routeNodeInstanceLoader a service that will provide routeNodeInstanceS based on their IDs.
1071      */
1072     public static ActionRequestValue from(ActionRequest actionRequest, 
1073             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1074         return convertActionRequest(actionRequest, null, routeNodeInstanceLoader);
1075     }
1076 
1077     private static ActionRequestValue convertActionRequest(ActionRequest actionRequest, ActionRequestValue parentActionRequestBo,
1078             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1079         if (actionRequest == null) {
1080             return null;
1081         }
1082         ActionRequestValue actionRequestBo = new ActionRequestFactory().createBlankActionRequest();
1083         populateActionRequest(actionRequestBo, actionRequest, routeNodeInstanceLoader);
1084         if (parentActionRequestBo != null) {
1085             actionRequestBo.setParentActionRequest(parentActionRequestBo);
1086             actionRequestBo.setParentActionRequestId(parentActionRequestBo.getActionRequestId());
1087         }
1088         if (actionRequest.getChildRequests() != null) {
1089             for (ActionRequest childRequest : actionRequest.getChildRequests()) {
1090                 actionRequestBo.getChildrenRequests().add(ActionRequestValue.convertActionRequest(childRequest, actionRequestBo, routeNodeInstanceLoader));
1091             }
1092         }
1093         return actionRequestBo;
1094     }
1095 
1096     /**
1097      * This method converts everything except for the parent and child requests
1098      */
1099     private static void populateActionRequest(ActionRequestValue actionRequestBo, ActionRequest actionRequest, 
1100             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1101 
1102         actionRequestBo.setActionRequested(actionRequest.getActionRequested().getCode());
1103         if (!StringUtils.isBlank(actionRequest.getId())) {
1104             actionRequestBo.setActionRequestId(actionRequest.getId());
1105         }
1106         
1107         if (actionRequest.getActionTaken() != null) {
1108             // actionRequestBo.setActionTaken(ActionTakenValue.from(actionRequest.getActionTaken()));
1109             if (!StringUtils.isBlank(actionRequest.getActionTaken().getId())) {
1110                 actionRequestBo.setActionTakenId(actionRequest.getActionTaken().getId());
1111             }
1112         }
1113         actionRequestBo.setAnnotation(actionRequest.getAnnotation());
1114         if (actionRequest.getRequestPolicy() != null) {
1115             actionRequestBo.setApprovePolicy(actionRequest.getRequestPolicy().getCode());
1116         }
1117         actionRequestBo.setCreateDate(new Timestamp(actionRequest.getDateCreated().getMillis()));
1118         actionRequestBo.setCurrentIndicator(actionRequest.isCurrent());
1119         if (actionRequest.getDelegationType() != null) {
1120             actionRequestBo.setDelegationType(actionRequest.getDelegationType());
1121         }
1122         //actionRequestBo.setDocVersion(actionRequest.?);
1123         actionRequestBo.setForceAction(actionRequest.isForceAction());
1124         actionRequestBo.setPriority(actionRequest.getPriority());
1125         actionRequestBo.setRouteLevel(actionRequest.getRouteLevel());
1126         actionRequestBo.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
1127         actionRequestBo.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
1128         actionRequestBo.setRecipientTypeCd(actionRequest.getRecipientType().getCode());
1129         actionRequestBo.setResponsibilityDesc(actionRequest.getResponsibilityDescription());
1130         if (!StringUtils.isBlank(actionRequest.getResponsibilityId())) {
1131             actionRequestBo.setResponsibilityId(actionRequest.getResponsibilityId());
1132         }
1133         actionRequestBo.setRoleName(actionRequest.getRoleName());
1134         String documentId = actionRequest.getDocumentId();
1135         if (documentId != null) {
1136             actionRequestBo.setDocumentId(documentId);
1137             actionRequestBo.setRouteHeader(KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId));
1138         }
1139 
1140         actionRequestBo.setStatus(actionRequest.getStatus().getCode());
1141         actionRequestBo.setPrincipalId(actionRequest.getPrincipalId());
1142         actionRequestBo.setGroupId(actionRequest.getGroupId());
1143         
1144         if (routeNodeInstanceLoader != null && !StringUtils.isBlank(actionRequest.getRouteNodeInstanceId())) {
1145             actionRequestBo.setNodeInstance(routeNodeInstanceLoader.load(actionRequest.getRouteNodeInstanceId()));
1146         }
1147     }
1148     
1149 }