View Javadoc

1   /**
2    * Copyright 2005-2012 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     	    return getPerson().getName();
255     	} else if (isGroupRequest()) {
256     		return getGroup().getName();
257     	} else if (isRoleRequest()) {
258     		return getRoleName();
259     	}
260     	return "";
261     }
262 
263     public Recipient getRecipient() {
264         if (getPrincipalId() != null) {
265             return new KimPrincipalRecipient(getPrincipal());
266         } else if (getGroupId() != null){
267             return new KimGroupRecipient(getGroup());
268         } else {
269         	return new RoleRecipient(this.getRoleName());
270         }
271     }
272 
273     public boolean isPending() {
274         return ActionRequestStatus.INITIALIZED.getCode().equals(getStatus()) || ActionRequestStatus.ACTIVATED.getCode().equals(getStatus());
275     }
276 
277     public String getStatusLabel() {
278         return CodeTranslator.getActionRequestStatusLabel(getStatus());
279     }
280 
281     public String getActionRequestedLabel() {
282     	if (StringUtils.isNotBlank(getRequestLabel())) {
283     		return getRequestLabel();
284     	}
285     	return CodeTranslator.getActionRequestLabel(getActionRequested());
286     }
287 
288     /**
289      * @return Returns the actionTaken.
290      */
291     public ActionTakenValue getActionTaken() {
292         return actionTaken;
293     }
294 
295     /**
296      * @param actionTaken
297      *            The actionTaken to set.
298      */
299     public void setActionTaken(ActionTakenValue actionTaken) {
300         this.actionTaken = actionTaken;
301     }
302 
303     /**
304      * @return Returns the actionRequested.
305      */
306     public String getActionRequested() {
307         return actionRequested;
308     }
309 
310     /**
311      * @param actionRequested
312      *            The actionRequested to set.
313      */
314     public void setActionRequested(String actionRequested) {
315         this.actionRequested = actionRequested;
316     }
317 
318     /**
319      * @return Returns the actionRequestId.
320      */
321     public String getActionRequestId() {
322         return actionRequestId;
323     }
324 
325     /**
326      * @param actionRequestId
327      *            The actionRequestId to set.
328      */
329     public void setActionRequestId(String actionRequestId) {
330         this.actionRequestId = actionRequestId;
331     }
332 
333     /**
334      * @return Returns the actionTakenId.
335      */
336     public String getActionTakenId() {
337         return actionTakenId;
338     }
339 
340     /**
341      * @param actionTakenId
342      *            The actionTakenId to set.
343      */
344     public void setActionTakenId(String actionTakenId) {
345         this.actionTakenId = actionTakenId;
346     }
347 
348     /**
349      * @return Returns the annotation.
350      */
351     public String getAnnotation() {
352         return annotation;
353     }
354 
355     /**
356      * @param annotation
357      *            The annotation to set.
358      */
359     public void setAnnotation(String annotation) {
360         this.annotation = annotation;
361     }
362 
363     /**
364      * @return Returns the createDate.
365      */
366     public java.sql.Timestamp getCreateDate() {
367         return createDate;
368     }
369 
370     /**
371      * @param createDate
372      *            The createDate to set.
373      */
374     public void setCreateDate(java.sql.Timestamp createDate) {
375         this.createDate = createDate;
376     }
377 
378     /**
379      * @return Returns the docVersion.
380      */
381     public Integer getDocVersion() {
382         return docVersion;
383     }
384 
385     /**
386      * @param docVersion
387      *            The docVersion to set.
388      */
389     public void setDocVersion(Integer docVersion) {
390         this.docVersion = docVersion;
391     }
392 
393     public String getPrincipalId() {
394         return principalId;
395     }
396 
397     public void setPrincipalId(String principalId) {
398         this.principalId = principalId;
399     }
400     
401     /**
402      * @return Returns the forceAction.
403      */
404     public Boolean getForceAction() {
405         return forceAction;
406     }
407 
408     /**
409      * @param forceAction
410      *            The forceAction to set.
411      */
412     public void setForceAction(Boolean forceAction) {
413         this.forceAction = forceAction;
414     }
415 
416     /**
417      * @return Returns the jrfVerNbr.
418      */
419     public Integer getJrfVerNbr() {
420         return jrfVerNbr;
421     }
422 
423     /**
424      * @param jrfVerNbr
425      *            The jrfVerNbr to set.
426      */
427     public void setJrfVerNbr(Integer jrfVerNbr) {
428         this.jrfVerNbr = jrfVerNbr;
429     }
430 
431     /**
432      * @return Returns the priority.
433      */
434     public Integer getPriority() {
435         return priority;
436     }
437 
438     /**
439      * @param priority
440      *            The priority to set.
441      */
442     public void setPriority(Integer priority) {
443         this.priority = priority;
444     }
445 
446     /**
447      * @return Returns the recipientTypeCd.
448      */
449     public String getRecipientTypeCd() {
450         return recipientTypeCd;
451     }
452 
453     /**
454      * @param recipientTypeCd
455      *            The recipientTypeCd to set.
456      */
457     public void setRecipientTypeCd(String recipientTypeCd) {
458         this.recipientTypeCd = recipientTypeCd;
459     }
460 
461     /**
462      * @return Returns the responsibilityDesc.
463      */
464     public String getResponsibilityDesc() {
465         return responsibilityDesc;
466     }
467 
468     /**
469      * @param responsibilityDesc
470      *            The responsibilityDesc to set.
471      */
472     public void setResponsibilityDesc(String responsibilityDesc) {
473         this.responsibilityDesc = responsibilityDesc;
474     }
475 
476     /**
477      * @return Returns the responsibilityId.
478      */
479     public String getResponsibilityId() {
480         return responsibilityId;
481     }
482 
483     /**
484      * @param responsibilityId
485      *            The responsibilityId to set.
486      */
487     public void setResponsibilityId(String responsibilityId) {
488         this.responsibilityId = responsibilityId;
489     }
490 
491     /**
492      * @return Returns the documentId.
493      */
494     public String getDocumentId() {
495         return documentId;
496     }
497 
498     public void setDocumentId(String documentId) {
499         this.documentId = documentId;
500     }
501 
502     public Integer getRouteLevel() {
503         return routeLevel;
504     }
505 
506     public void setRouteLevel(Integer routeLevel) {
507         this.routeLevel = routeLevel;
508     }
509 
510     public String getStatus() {
511         return status;
512     }
513 
514     public void setStatus(String status) {
515         this.status = status;
516     }
517 
518     public String getGroupId() {
519         return groupId;
520     }
521 
522     public void setGroupId(String groupId) {
523         this.groupId = groupId;
524     }
525 
526     public boolean isInitialized() {
527         return ActionRequestStatus.INITIALIZED.getCode().equals(getStatus());
528     }
529 
530     public boolean isActive() {
531         return ActionRequestStatus.ACTIVATED.getCode().equals(getStatus());
532     }
533 
534     public boolean isApproveOrCompleteRequest() {
535         return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested()) || KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
536     }
537 
538     public boolean isDone() {
539         return ActionRequestStatus.DONE.getCode().equals(getStatus());
540     }
541 
542     public boolean isReviewerUser() {
543         return RecipientType.PRINCIPAL.getCode().equals(getRecipientTypeCd());
544     }
545 
546     /**
547      * Determines whether the specified principalId is in the recipient graph of this action request
548      * @param principalId the principal id to check
549      * @return whether the specified principalId is in the recipient graph of this action request
550      */
551     public boolean isRecipientRoutedRequest(String principalId) {
552     	//before altering this method it is used in checkRouteLogAuthentication
553     	//don't break that method
554     	if (principalId == null || "".equals(principalId)) {
555     		return false;
556     	}
557 
558     	boolean isRecipientInGraph = false;
559     	if (isReviewerUser()) {
560     			isRecipientInGraph = getPrincipalId().equals(principalId);
561     	} else if (isGroupRequest()) {
562     		Group group = getGroup();
563 			if (group == null){
564 				LOG.error("Was unable to retrieve workgroup " + getGroupId());
565 			}
566     		isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, group.getId());
567     	}
568 
569 
570         for (ActionRequestValue childRequest : getChildrenRequests())
571         {
572             isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(principalId);
573         }
574 
575     	return isRecipientInGraph;
576     }
577 
578     public boolean isRecipientRoutedRequest(Recipient recipient) {
579     	//before altering this method it is used in checkRouteLogAuthentication
580     	//don't break that method
581     	if (recipient == null) {
582     		return false;
583     	}
584 
585     	boolean isRecipientInGraph = false;
586     	if (isReviewerUser()) {
587     		if (recipient instanceof KimPrincipalRecipient) {
588     			isRecipientInGraph = getPrincipalId().equals(((KimPrincipalRecipient) recipient).getPrincipalId());
589     		} else if (recipient instanceof KimGroupRecipient){
590     			isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(getPrincipalId(), ((KimGroupRecipient)recipient).getGroup().getId());
591     		}
592 
593     	} else if (isGroupRequest()) {
594     		Group group = getGroup();
595 			if (group == null){
596 				LOG.error("Was unable to retrieve workgroup " + getGroupId());
597 			}
598     		if (recipient instanceof KimPrincipalRecipient) {
599     			KimPrincipalRecipient principalRecipient = (KimPrincipalRecipient)recipient;
600     			isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalRecipient.getPrincipalId(), group.getId());
601     		} else if (recipient instanceof KimGroupRecipient) {
602     			isRecipientInGraph = ((KimGroupRecipient) recipient).getGroup().getId().equals(group.getId());
603     		}
604     	}
605 
606 
607         for (ActionRequestValue childRequest : getChildrenRequests())
608         {
609             isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(recipient);
610         }
611 
612     	return isRecipientInGraph;
613     }
614 
615     public boolean isGroupRequest(){
616     	return RecipientType.GROUP.getCode().equals(getRecipientTypeCd());
617     }
618 
619     public boolean isRoleRequest() {
620         return RecipientType.ROLE.getCode().equals(getRecipientTypeCd());
621     }
622 
623     public boolean isAcknowledgeRequest() {
624         return KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(getActionRequested());
625     }
626 
627     public boolean isApproveRequest() {
628         return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested());
629     }
630 
631     public boolean isCompleteRequst() {
632         return KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
633     }
634 
635     public boolean isFYIRequest() {
636         return KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(getActionRequested());
637     }
638 
639     /**
640      * 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)
641      *
642      * @param code1
643      * @param code2
644      * @param completeAndApproveTheSame
645      * @return -1 if less than, 0 if equal, 1 if greater than
646      */
647     public static int compareActionCode(String code1, String code2, boolean completeAndApproveTheSame) {
648     	int cutoff = Integer.MAX_VALUE;
649     	if (completeAndApproveTheSame) {
650     		// hacked so that APPROVE and COMPLETE are equal
651     		cutoff = ACTION_CODE_RANK.length() - 3;
652     	}
653         Integer code1Index = Math.min(ACTION_CODE_RANK.indexOf(code1), cutoff);
654         Integer code2Index = Math.min(ACTION_CODE_RANK.indexOf(code2), cutoff);
655         return code1Index.compareTo(code2Index);
656     }
657 
658     /**
659      * 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
660      *
661      * @param type1
662      * @param type2
663      * @return -1 if less than, 0 if equal, 1 if greater than
664      */
665     public static int compareRecipientType(String type1, String type2) {
666         Integer type1Index = RECIPIENT_TYPE_RANK.indexOf(type1);
667         Integer type2Index = RECIPIENT_TYPE_RANK.indexOf(type2);
668         return type1Index.compareTo(type2Index);
669     }
670 
671     public static int compareDelegationType(DelegationType type1, DelegationType type2) {
672     	Integer type1Index = DELEGATION_TYPE_RANK.indexOf(type1);
673         Integer type2Index = DELEGATION_TYPE_RANK.indexOf(type2);
674         return type1Index.compareTo(type2Index);
675     }
676 
677     public List<ActionItem> getActionItems() {
678     	if (this.simulatedActionItems == null || this.simulatedActionItems.isEmpty()) {
679     		return (List<ActionItem>) KEWServiceLocator.getActionListService().findByActionRequestId(actionRequestId);
680     	} else {
681     		return this.simulatedActionItems;
682     	}
683     }
684 
685     public List<ActionItem> getSimulatedActionItems() {
686     	if (this.simulatedActionItems == null) {
687     		this.simulatedActionItems = new ArrayList<ActionItem>();
688     	}
689 		return this.simulatedActionItems;
690 	}
691 
692 	public void setSimulatedActionItems(List<ActionItem> simulatedActionItems) {
693 		this.simulatedActionItems = simulatedActionItems;
694 	}
695 
696 	public Boolean getCurrentIndicator() {
697         return currentIndicator;
698     }
699 
700     public void setCurrentIndicator(Boolean currentIndicator) {
701         this.currentIndicator = currentIndicator;
702     }
703 
704     public String getParentActionRequestId() {
705         return parentActionRequestId;
706     }
707 
708     public void setParentActionRequestId(String parentActionRequestId) {
709         this.parentActionRequestId = parentActionRequestId;
710     }
711 
712     public ActionRequestValue getParentActionRequest() {
713         return parentActionRequest;
714     }
715 
716     public void setParentActionRequest(ActionRequestValue parentActionRequest) {
717         this.parentActionRequest = parentActionRequest;
718     }
719 
720     public List<ActionRequestValue> getChildrenRequests() {
721         return childrenRequests;
722     }
723 
724     public void setChildrenRequests(List<ActionRequestValue> childrenRequests) {
725         this.childrenRequests = childrenRequests;
726     }
727 
728     public String getQualifiedRoleName() {
729         return qualifiedRoleName;
730     }
731 
732     public void setQualifiedRoleName(String roleName) {
733         this.qualifiedRoleName = roleName;
734     }
735 
736     public DelegationType getDelegationType() {
737         return DelegationType.fromCode(delegationTypeCode);
738     }
739 
740     public void setDelegationType(DelegationType delegationPolicy) {
741         this.delegationTypeCode = delegationPolicy == null ? null : delegationPolicy.getCode();
742     }
743 
744 
745     public String getDelegationTypeCode() {
746         return delegationTypeCode;
747     }
748 
749     public void setDelegationTypeCode(String delegationTypeCode) {
750         this.delegationTypeCode = delegationTypeCode;
751     }
752 
753     public String getRoleName() {
754         return roleName;
755     }
756 
757     public void setRoleName(String roleName) {
758         this.roleName = roleName;
759     }
760 
761     public String getApprovePolicy() {
762         return approvePolicy;
763     }
764 
765     public void setApprovePolicy(String requestType) {
766         this.approvePolicy = requestType;
767     }
768 
769     public boolean getHasApprovePolicy() {
770         return getApprovePolicy() != null;
771     }
772 
773     public boolean isDeactivated() {
774         return ActionRequestStatus.DONE.getCode().equals(getStatus());
775     }
776 
777     public boolean hasParent() {
778         return getParentActionRequest() != null;
779     }
780 
781     public boolean hasChild(ActionRequestValue actionRequest) {
782         if (actionRequest == null)
783             return false;
784         String actionRequestId = actionRequest.getActionRequestId();
785         for (Iterator<ActionRequestValue> iter = getChildrenRequests().iterator(); iter.hasNext();) {
786             ActionRequestValue childRequest = iter.next();
787             if (childRequest.equals(actionRequest) || (actionRequestId != null && actionRequestId.equals(childRequest.getActionRequestId()))) {
788                 return true;
789             }
790         }
791         return false;
792     }
793 
794     public String getDisplayStatus() {
795         return displayStatus;
796     }
797 
798     public void setDisplayStatus(String displayStatus) {
799         this.displayStatus = displayStatus;
800     }
801 
802     public String getQualifiedRoleNameLabel() {
803         return qualifiedRoleNameLabel;
804     }
805 
806     public void setQualifiedRoleNameLabel(String qualifiedRoleNameLabel) {
807         this.qualifiedRoleNameLabel = qualifiedRoleNameLabel;
808     }
809 
810     public String getCreateDateString() {
811         if (createDateString == null || createDateString.trim().equals("")) {
812             return RiceConstants.getDefaultDateFormat().format(getCreateDate());
813         } else {
814             return createDateString;
815         }
816     }
817 
818     public void setCreateDateString(String createDateString) {
819         this.createDateString = createDateString;
820     }
821 
822     public RouteNodeInstance getNodeInstance() {
823 		return nodeInstance;
824 	}
825 
826     public String getPotentialNodeName() {
827         return (getNodeInstance() == null ? "" : getNodeInstance().getName());
828     }
829 
830 	public void setNodeInstance(RouteNodeInstance nodeInstance) {
831 		this.nodeInstance = nodeInstance;
832 	}
833 
834 	public String getRecipientTypeLabel() {
835 		return RecipientType.fromCode(getRecipientTypeCd()).getLabel();
836     }
837 
838     public RuleBaseValues getRuleBaseValues(){
839         if(ruleBaseValuesId != null){
840             return getRuleService().findRuleBaseValuesById(ruleBaseValuesId);
841         }
842         return null;
843     }
844     public String getRuleBaseValuesId() {
845         return ruleBaseValuesId;
846     }
847 
848     public void setRuleBaseValuesId(String ruleBaseValuesId) {
849         this.ruleBaseValuesId = ruleBaseValuesId;
850     }
851     
852 	private RuleServiceInternal getRuleService() {
853         return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
854     }
855 
856     public boolean isPrimaryDelegator() {
857         boolean primaryDelegator = false;
858         for (Iterator<ActionRequestValue> iter = childrenRequests.iterator(); iter.hasNext();) {
859             ActionRequestValue childRequest = iter.next();
860             primaryDelegator = DelegationType.PRIMARY.equals(childRequest.getDelegationType()) || primaryDelegator;
861         }
862         return primaryDelegator;
863     }
864 
865     /**
866      * Used to get primary delegate names on route log in the 'Requested Of' section so primary delegate requests
867      * list the delegate and not the delegator as having the request 'IN ACTION LIST'.  This method doesn't recurse
868      * and therefore assume an AR structure.
869      *
870      * @return primary delgate requests
871      */
872     public List<ActionRequestValue> getPrimaryDelegateRequests() {
873         List<ActionRequestValue> primaryDelegateRequests = new ArrayList<ActionRequestValue>();
874         for (ActionRequestValue childRequest : childrenRequests)
875         {
876             if (DelegationType.PRIMARY.equals(childRequest.getDelegationType()))
877             {
878                 if (childRequest.isRoleRequest())
879                 {
880                     for (ActionRequestValue actionRequestValue : childRequest.getChildrenRequests())
881                     {
882                         primaryDelegateRequests.add(actionRequestValue);
883                     }
884                 } else
885                 {
886                 	primaryDelegateRequests.add(childRequest);
887                 }
888             }
889         }
890         return primaryDelegateRequests;
891     }
892 
893     public boolean isAdHocRequest() {                                          
894     	return KewApiConstants.ADHOC_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
895     }
896 
897     public boolean isGeneratedRequest() {
898     	return KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(getResponsibilityId());
899     }
900 
901     public boolean isExceptionRequest() {
902     	return KewApiConstants.EXCEPTION_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
903     }
904 
905     public boolean isRouteModuleRequest() {
906     	// FIXME: KULRICE-5201 switched rsp_id to a varchar, so the comparison below is no longer valid
907 //    	return getResponsibilityId() > 0;
908     	// TODO: KULRICE-5329 Verify that this code below makes sense 
909     	return getResponsibilityId() != null && !KewApiConstants.SPECIAL_RESPONSIBILITY_ID_SET.contains(getResponsibilityId());
910     }
911 
912     public String toString() {
913         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
914             .append("actionRequestId", actionRequestId)
915             .append("actionRequested", actionRequested)
916             .append("documentId", documentId)
917             .append("status", status)
918             .append("responsibilityId", responsibilityId)
919             .append("groupId", groupId)
920             .append("recipientTypeCd", recipientTypeCd)
921             .append("priority", priority)
922             .append("routeLevel", routeLevel)
923             .append("actionTakenId", actionTakenId)
924             .append("docVersion", docVersion)
925             .append("createDate", createDate)
926             .append("responsibilityDesc", responsibilityDesc)
927             .append("annotation", annotation)
928             .append("jrfVerNbr", jrfVerNbr)
929             .append("principalId", principalId)
930             .append("forceAction", forceAction)
931             .append("parentActionRequestId", parentActionRequestId)
932             .append("qualifiedRoleName", qualifiedRoleName)
933             .append("roleName", roleName)
934             .append("qualifiedRoleNameLabel", qualifiedRoleNameLabel)
935             .append("displayStatus", displayStatus)
936             .append("ruleBaseValuesId", ruleBaseValuesId)
937             .append("delegationType", delegationTypeCode)
938             .append("approvePolicy", approvePolicy)
939             .append("actionTaken", actionTaken)
940             .append("currentIndicator", currentIndicator)
941             .append("createDateString", createDateString)
942             .append("nodeInstance", nodeInstance).toString();
943     }
944 
945 	public String getRequestLabel() {
946 		return this.requestLabel;
947 	}
948 
949 	public void setRequestLabel(String requestLabel) {
950 		this.requestLabel = requestLabel;
951 	}
952 
953     public String getGroupName() {
954         return KimApiServiceLocator.getGroupService().getGroup(this.groupId).getName();
955     }
956 
957 	/**
958 	 * @return the resolveResponsibility
959 	 */
960 	public boolean getResolveResponsibility() {
961 		return this.resolveResponsibility;
962 	}
963 
964 	/**
965 	 * @param resolveResponsibility the resolveResponsibility to set
966 	 */
967 	public void setResolveResponsibility(boolean resolveResponsibility) {
968 		this.resolveResponsibility = resolveResponsibility;
969 	}
970 
971 	public DocumentRouteHeaderValue getRouteHeader() {
972 		if (this.routeHeader == null && this.documentId != null) {
973 			this.routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(this.documentId);
974 		}
975 		return this.routeHeader;
976 	}
977 
978 	public void setRouteHeader(DocumentRouteHeaderValue routeHeader) {
979 		this.routeHeader = routeHeader;
980 	}
981 	
982 	public static ActionRequest to(ActionRequestValue actionRequestBo) {
983 		if (actionRequestBo == null) {
984 			return null;
985 		}
986 		return createActionRequestBuilder(actionRequestBo).build();
987 	}
988 	
989 	private static ActionRequest.Builder createActionRequestBuilder(ActionRequestValue actionRequestBo) {
990 		ActionRequest.Builder builder = ActionRequest.Builder.create(actionRequestBo.getActionRequestId(),
991 				ActionRequestType.fromCode(actionRequestBo.getActionRequested()),
992 				ActionRequestStatus.fromCode(actionRequestBo.getStatus()),
993 				actionRequestBo.getResponsibilityId(),
994 				actionRequestBo.getDocumentId(),
995 				RecipientType.fromCode(actionRequestBo.getRecipientTypeCd()));
996 		if (actionRequestBo.getActionTaken() != null) {
997 			builder.setActionTaken(ActionTaken.Builder.create(ActionTakenValue.to(actionRequestBo.getActionTaken())));
998 		}
999 		builder.setAnnotation(actionRequestBo.getAnnotation());
1000 		builder.setCurrent(actionRequestBo.getCurrentIndicator().booleanValue());
1001 		builder.setDateCreated(new DateTime(actionRequestBo.getCreateDate().getTime()));
1002 		if (actionRequestBo.getDelegationType() != null) {
1003 			builder.setDelegationType(actionRequestBo.getDelegationType());
1004 		}
1005 		builder.setForceAction(actionRequestBo.getForceAction().booleanValue());
1006 		builder.setGroupId(actionRequestBo.getGroupId());
1007 		builder.setNodeName(actionRequestBo.getPotentialNodeName());
1008 		if (actionRequestBo.getParentActionRequestId() != null) {
1009 			builder.setParentActionRequestId(actionRequestBo.getParentActionRequestId());
1010 		}
1011 		builder.setPrincipalId(actionRequestBo.getPrincipalId());
1012 		if (actionRequestBo.getPriority() == null) {
1013 			builder.setPriority(KewApiConstants.ACTION_REQUEST_DEFAULT_PRIORITY);
1014 		} else {
1015             builder.setPriority(actionRequestBo.getPriority().intValue());
1016         }
1017         if (actionRequestBo.getRouteLevel() == null ) {
1018             builder.setRouteLevel(0);
1019         } else {
1020             builder.setRouteLevel(actionRequestBo.getRouteLevel().intValue());
1021         }
1022 		builder.setQualifiedRoleName(actionRequestBo.getQualifiedRoleName());
1023 		builder.setQualifiedRoleNameLabel(actionRequestBo.getQualifiedRoleNameLabel());
1024 		builder.setRequestLabel(actionRequestBo.getRequestLabel());
1025 		if (!StringUtils.isBlank(actionRequestBo.getApprovePolicy())) {
1026 			builder.setRequestPolicy(ActionRequestPolicy.fromCode(actionRequestBo.getApprovePolicy()));
1027 		}
1028 		builder.setResponsibilityDescription(actionRequestBo.getResponsibilityDesc());
1029 		builder.setRoleName(actionRequestBo.getRoleName());
1030 		if (actionRequestBo.getNodeInstance() != null) {
1031 			builder.setRouteNodeInstanceId(actionRequestBo.getNodeInstance().getRouteNodeInstanceId());
1032 		}
1033 		
1034 		List<ActionRequest.Builder> childRequests = new ArrayList<ActionRequest.Builder>();
1035 		if (actionRequestBo.getChildrenRequests() != null) {
1036 			for (ActionRequestValue childActionRequestBo : actionRequestBo.getChildrenRequests()) {
1037 				childRequests.add(createActionRequestBuilder(childActionRequestBo));
1038 			}
1039 		}
1040 		builder.setChildRequests(childRequests);
1041 		return builder;
1042 	}
1043 	
1044     /**
1045      * TODO - this javadoc copied from DTOConverter, needs to be updated!
1046      * 
1047      * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1048      * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1049      * references in the conversion. NOTE: This method's primary purpose is to convert ActionRequestVOs returned from a
1050      * RouteModule. Incidentally, the DTO's returned from the route module will be lacking some information (like the node
1051      * instance) so no attempts are made to convert this data since further initialization is handled by a higher level
1052      * component (namely ActionRequestService.initializeActionRequestGraph).
1053      */
1054     public static ActionRequestValue from(ActionRequest actionRequest) {
1055         return ActionRequestValue.from(actionRequest, null);
1056     }
1057     
1058     /**
1059      * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1060      * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1061      * references in the conversion. 
1062      * @param routeNodeInstanceLoader a service that will provide routeNodeInstanceS based on their IDs.
1063      */
1064     public static ActionRequestValue from(ActionRequest actionRequest, 
1065             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1066         return convertActionRequest(actionRequest, null, routeNodeInstanceLoader);
1067     }
1068 
1069     private static ActionRequestValue convertActionRequest(ActionRequest actionRequest, ActionRequestValue parentActionRequestBo,
1070             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1071         if (actionRequest == null) {
1072             return null;
1073         }
1074         ActionRequestValue actionRequestBo = new ActionRequestFactory().createBlankActionRequest();
1075         populateActionRequest(actionRequestBo, actionRequest, routeNodeInstanceLoader);
1076         if (parentActionRequestBo != null) {
1077             actionRequestBo.setParentActionRequest(parentActionRequestBo);
1078             actionRequestBo.setParentActionRequestId(parentActionRequestBo.getActionRequestId());
1079         }
1080         if (actionRequest.getChildRequests() != null) {
1081             for (ActionRequest childRequest : actionRequest.getChildRequests()) {
1082                 actionRequestBo.getChildrenRequests().add(ActionRequestValue.convertActionRequest(childRequest, actionRequestBo, routeNodeInstanceLoader));
1083             }
1084         }
1085         return actionRequestBo;
1086     }
1087 
1088     /**
1089      * This method converts everything except for the parent and child requests
1090      */
1091     private static void populateActionRequest(ActionRequestValue actionRequestBo, ActionRequest actionRequest, 
1092             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1093 
1094         actionRequestBo.setActionRequested(actionRequest.getActionRequested().getCode());
1095         if (!StringUtils.isBlank(actionRequest.getId())) {
1096             actionRequestBo.setActionRequestId(actionRequest.getId());
1097         }
1098         
1099         if (actionRequest.getActionTaken() != null) {
1100             // actionRequestBo.setActionTaken(ActionTakenValue.from(actionRequest.getActionTaken()));
1101             if (!StringUtils.isBlank(actionRequest.getActionTaken().getId())) {
1102                 actionRequestBo.setActionTakenId(actionRequest.getActionTaken().getId());
1103             }
1104         }
1105         actionRequestBo.setAnnotation(actionRequest.getAnnotation());
1106         if (actionRequest.getRequestPolicy() != null) {
1107             actionRequestBo.setApprovePolicy(actionRequest.getRequestPolicy().getCode());
1108         }
1109         actionRequestBo.setCreateDate(new Timestamp(actionRequest.getDateCreated().getMillis()));
1110         actionRequestBo.setCurrentIndicator(actionRequest.isCurrent());
1111         if (actionRequest.getDelegationType() != null) {
1112             actionRequestBo.setDelegationType(actionRequest.getDelegationType());
1113         }
1114         //actionRequestBo.setDocVersion(actionRequest.?);
1115         actionRequestBo.setForceAction(actionRequest.isForceAction());
1116         actionRequestBo.setPriority(actionRequest.getPriority());
1117         actionRequestBo.setRouteLevel(actionRequest.getRouteLevel());
1118         actionRequestBo.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
1119         actionRequestBo.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
1120         actionRequestBo.setRecipientTypeCd(actionRequest.getRecipientType().getCode());
1121         actionRequestBo.setResponsibilityDesc(actionRequest.getResponsibilityDescription());
1122         if (!StringUtils.isBlank(actionRequest.getResponsibilityId())) {
1123             actionRequestBo.setResponsibilityId(actionRequest.getResponsibilityId());
1124         }
1125         actionRequestBo.setRoleName(actionRequest.getRoleName());
1126         String documentId = actionRequest.getDocumentId();
1127         if (documentId != null) {
1128             actionRequestBo.setDocumentId(documentId);
1129             actionRequestBo.setRouteHeader(KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId));
1130         }
1131 
1132         actionRequestBo.setStatus(actionRequest.getStatus().getCode());
1133         actionRequestBo.setPrincipalId(actionRequest.getPrincipalId());
1134         actionRequestBo.setGroupId(actionRequest.getGroupId());
1135         
1136         if (routeNodeInstanceLoader != null && !StringUtils.isBlank(actionRequest.getRouteNodeInstanceId())) {
1137             actionRequestBo.setNodeInstance(routeNodeInstanceLoader.load(actionRequest.getRouteNodeInstanceId()));
1138         }
1139     }
1140     
1141 }