View Javadoc

1   /**
2    * Copyright 2005-2011 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     public boolean isRecipientRoutedRequest(String principalId) {
547     	//before altering this method it is used in checkRouteLogAuthentication
548     	//don't break that method
549     	if (principalId == null || "".equals(principalId)) {
550     		return false;
551     	}
552 
553     	boolean isRecipientInGraph = false;
554     	if (isReviewerUser()) {
555     			isRecipientInGraph = getPrincipalId().equals(principalId);
556     	} else if (isGroupRequest()) {
557     		Group group = getGroup();
558 			if (group == null){
559 				LOG.error("Was unable to retrieve workgroup " + getGroupId());
560 			}
561     		isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalId, group.getId());
562     	}
563 
564 
565         for (ActionRequestValue childRequest : getChildrenRequests())
566         {
567             isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(principalId);
568         }
569 
570     	return isRecipientInGraph;
571     }
572 
573     public boolean isRecipientRoutedRequest(Recipient recipient) {
574     	//before altering this method it is used in checkRouteLogAuthentication
575     	//don't break that method
576     	if (recipient == null) {
577     		return false;
578     	}
579 
580     	boolean isRecipientInGraph = false;
581     	if (isReviewerUser()) {
582     		if (recipient instanceof KimPrincipalRecipient) {
583     			isRecipientInGraph = getPrincipalId().equals(((KimPrincipalRecipient) recipient).getPrincipalId());
584     		} else if (recipient instanceof KimGroupRecipient){
585     			isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(getPrincipalId(), ((KimGroupRecipient)recipient).getGroup().getId());
586     		}
587 
588     	} else if (isGroupRequest()) {
589     		Group group = getGroup();
590 			if (group == null){
591 				LOG.error("Was unable to retrieve workgroup " + getGroupId());
592 			}
593     		if (recipient instanceof KimPrincipalRecipient) {
594     			KimPrincipalRecipient principalRecipient = (KimPrincipalRecipient)recipient;
595     			isRecipientInGraph = KimApiServiceLocator.getGroupService().isMemberOfGroup(principalRecipient.getPrincipalId(), group.getId());
596     		} else if (recipient instanceof KimGroupRecipient) {
597     			isRecipientInGraph = ((KimGroupRecipient) recipient).getGroup().getId().equals(group.getId());
598     		}
599     	}
600 
601 
602         for (ActionRequestValue childRequest : getChildrenRequests())
603         {
604             isRecipientInGraph = isRecipientInGraph || childRequest.isRecipientRoutedRequest(recipient);
605         }
606 
607     	return isRecipientInGraph;
608     }
609 
610     public boolean isGroupRequest(){
611     	return RecipientType.GROUP.getCode().equals(getRecipientTypeCd());
612     }
613 
614     public boolean isRoleRequest() {
615         return RecipientType.ROLE.getCode().equals(getRecipientTypeCd());
616     }
617 
618     public boolean isAcknowledgeRequest() {
619         return KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(getActionRequested());
620     }
621 
622     public boolean isApproveRequest() {
623         return KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(getActionRequested());
624     }
625 
626     public boolean isCompleteRequst() {
627         return KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(getActionRequested());
628     }
629 
630     public boolean isFYIRequest() {
631         return KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(getActionRequested());
632     }
633 
634     /**
635      * 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)
636      *
637      * @param code1
638      * @param code2
639      * @param completeAndApproveTheSame
640      * @return -1 if less than, 0 if equal, 1 if greater than
641      */
642     public static int compareActionCode(String code1, String code2, boolean completeAndApproveTheSame) {
643     	int cutoff = Integer.MAX_VALUE;
644     	if (completeAndApproveTheSame) {
645     		// hacked so that APPROVE and COMPLETE are equal
646     		cutoff = ACTION_CODE_RANK.length() - 3;
647     	}
648         Integer code1Index = Math.min(ACTION_CODE_RANK.indexOf(code1), cutoff);
649         Integer code2Index = Math.min(ACTION_CODE_RANK.indexOf(code2), cutoff);
650         return code1Index.compareTo(code2Index);
651     }
652 
653     /**
654      * 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
655      *
656      * @param type1
657      * @param type2
658      * @return -1 if less than, 0 if equal, 1 if greater than
659      */
660     public static int compareRecipientType(String type1, String type2) {
661         Integer type1Index = RECIPIENT_TYPE_RANK.indexOf(type1);
662         Integer type2Index = RECIPIENT_TYPE_RANK.indexOf(type2);
663         return type1Index.compareTo(type2Index);
664     }
665 
666     public static int compareDelegationType(DelegationType type1, DelegationType type2) {
667     	Integer type1Index = DELEGATION_TYPE_RANK.indexOf(type1);
668         Integer type2Index = DELEGATION_TYPE_RANK.indexOf(type2);
669         return type1Index.compareTo(type2Index);
670     }
671 
672     public List<ActionItem> getActionItems() {
673     	if (this.simulatedActionItems == null || this.simulatedActionItems.isEmpty()) {
674     		return (List<ActionItem>) KEWServiceLocator.getActionListService().findByActionRequestId(actionRequestId);
675     	} else {
676     		return this.simulatedActionItems;
677     	}
678     }
679 
680     public List<ActionItem> getSimulatedActionItems() {
681     	if (this.simulatedActionItems == null) {
682     		this.simulatedActionItems = new ArrayList<ActionItem>();
683     	}
684 		return this.simulatedActionItems;
685 	}
686 
687 	public void setSimulatedActionItems(List<ActionItem> simulatedActionItems) {
688 		this.simulatedActionItems = simulatedActionItems;
689 	}
690 
691 	public Boolean getCurrentIndicator() {
692         return currentIndicator;
693     }
694 
695     public void setCurrentIndicator(Boolean currentIndicator) {
696         this.currentIndicator = currentIndicator;
697     }
698 
699     public String getParentActionRequestId() {
700         return parentActionRequestId;
701     }
702 
703     public void setParentActionRequestId(String parentActionRequestId) {
704         this.parentActionRequestId = parentActionRequestId;
705     }
706 
707     public ActionRequestValue getParentActionRequest() {
708         return parentActionRequest;
709     }
710 
711     public void setParentActionRequest(ActionRequestValue parentActionRequest) {
712         this.parentActionRequest = parentActionRequest;
713     }
714 
715     public List<ActionRequestValue> getChildrenRequests() {
716         return childrenRequests;
717     }
718 
719     public void setChildrenRequests(List<ActionRequestValue> childrenRequests) {
720         this.childrenRequests = childrenRequests;
721     }
722 
723     public String getQualifiedRoleName() {
724         return qualifiedRoleName;
725     }
726 
727     public void setQualifiedRoleName(String roleName) {
728         this.qualifiedRoleName = roleName;
729     }
730 
731     public DelegationType getDelegationType() {
732         return DelegationType.fromCode(delegationTypeCode);
733     }
734 
735     public void setDelegationType(DelegationType delegationPolicy) {
736         this.delegationTypeCode = delegationPolicy == null ? null : delegationPolicy.getCode();
737     }
738 
739 
740     public String getDelegationTypeCode() {
741         return delegationTypeCode;
742     }
743 
744     public void setDelegationTypeCode(String delegationTypeCode) {
745         this.delegationTypeCode = delegationTypeCode;
746     }
747 
748     public String getRoleName() {
749         return roleName;
750     }
751 
752     public void setRoleName(String roleName) {
753         this.roleName = roleName;
754     }
755 
756     public String getApprovePolicy() {
757         return approvePolicy;
758     }
759 
760     public void setApprovePolicy(String requestType) {
761         this.approvePolicy = requestType;
762     }
763 
764     public boolean getHasApprovePolicy() {
765         return getApprovePolicy() != null;
766     }
767 
768     public boolean isDeactivated() {
769         return ActionRequestStatus.DONE.getCode().equals(getStatus());
770     }
771 
772     public boolean hasParent() {
773         return getParentActionRequest() != null;
774     }
775 
776     public boolean hasChild(ActionRequestValue actionRequest) {
777         if (actionRequest == null)
778             return false;
779         String actionRequestId = actionRequest.getActionRequestId();
780         for (Iterator<ActionRequestValue> iter = getChildrenRequests().iterator(); iter.hasNext();) {
781             ActionRequestValue childRequest = iter.next();
782             if (childRequest.equals(actionRequest) || (actionRequestId != null && actionRequestId.equals(childRequest.getActionRequestId()))) {
783                 return true;
784             }
785         }
786         return false;
787     }
788 
789     public String getDisplayStatus() {
790         return displayStatus;
791     }
792 
793     public void setDisplayStatus(String displayStatus) {
794         this.displayStatus = displayStatus;
795     }
796 
797     public String getQualifiedRoleNameLabel() {
798         return qualifiedRoleNameLabel;
799     }
800 
801     public void setQualifiedRoleNameLabel(String qualifiedRoleNameLabel) {
802         this.qualifiedRoleNameLabel = qualifiedRoleNameLabel;
803     }
804 
805     public String getCreateDateString() {
806         if (createDateString == null || createDateString.trim().equals("")) {
807             return RiceConstants.getDefaultDateFormat().format(getCreateDate());
808         } else {
809             return createDateString;
810         }
811     }
812 
813     public void setCreateDateString(String createDateString) {
814         this.createDateString = createDateString;
815     }
816 
817     public RouteNodeInstance getNodeInstance() {
818 		return nodeInstance;
819 	}
820 
821     public String getPotentialNodeName() {
822         return (getNodeInstance() == null ? "" : getNodeInstance().getName());
823     }
824 
825 	public void setNodeInstance(RouteNodeInstance nodeInstance) {
826 		this.nodeInstance = nodeInstance;
827 	}
828 
829 	public String getRecipientTypeLabel() {
830 		return RecipientType.fromCode(getRecipientTypeCd()).getLabel();
831     }
832 
833     public RuleBaseValues getRuleBaseValues(){
834         if(ruleBaseValuesId != null){
835             return getRuleService().findRuleBaseValuesById(ruleBaseValuesId);
836         }
837         return null;
838     }
839     public String getRuleBaseValuesId() {
840         return ruleBaseValuesId;
841     }
842 
843     public void setRuleBaseValuesId(String ruleBaseValuesId) {
844         this.ruleBaseValuesId = ruleBaseValuesId;
845     }
846     
847 	private RuleServiceInternal getRuleService() {
848         return (RuleServiceInternal) KEWServiceLocator.getService(KEWServiceLocator.RULE_SERVICE);
849     }
850 
851     public boolean isPrimaryDelegator() {
852         boolean primaryDelegator = false;
853         for (Iterator<ActionRequestValue> iter = childrenRequests.iterator(); iter.hasNext();) {
854             ActionRequestValue childRequest = iter.next();
855             primaryDelegator = DelegationType.PRIMARY.equals(childRequest.getDelegationType()) || primaryDelegator;
856         }
857         return primaryDelegator;
858     }
859 
860     /**
861      * Used to get primary delegate names on route log in the 'Requested Of' section so primary delegate requests
862      * list the delegate and not the delegator as having the request 'IN ACTION LIST'.  This method doesn't recurse
863      * and therefore assume an AR structure.
864      *
865      * @return primary delgate requests
866      */
867     public List<ActionRequestValue> getPrimaryDelegateRequests() {
868         List<ActionRequestValue> primaryDelegateRequests = new ArrayList<ActionRequestValue>();
869         for (ActionRequestValue childRequest : childrenRequests)
870         {
871             if (DelegationType.PRIMARY.equals(childRequest.getDelegationType()))
872             {
873                 if (childRequest.isRoleRequest())
874                 {
875                     for (ActionRequestValue actionRequestValue : childRequest.getChildrenRequests())
876                     {
877                         primaryDelegateRequests.add(actionRequestValue);
878                     }
879                 } else
880                 {
881                 	primaryDelegateRequests.add(childRequest);
882                 }
883             }
884         }
885         return primaryDelegateRequests;
886     }
887 
888     public boolean isAdHocRequest() {                                          
889     	return KewApiConstants.ADHOC_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
890     }
891 
892     public boolean isGeneratedRequest() {
893     	return KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID.equals(getResponsibilityId());
894     }
895 
896     public boolean isExceptionRequest() {
897     	return KewApiConstants.EXCEPTION_REQUEST_RESPONSIBILITY_ID.equals(getResponsibilityId());
898     }
899 
900     public boolean isRouteModuleRequest() {
901     	// FIXME: KULRICE-5201 switched rsp_id to a varchar, so the comparison below is no longer valid
902 //    	return getResponsibilityId() > 0;
903     	// TODO: KULRICE-5329 Verify that this code below makes sense 
904     	return getResponsibilityId() != null && !KewApiConstants.SPECIAL_RESPONSIBILITY_ID_SET.contains(getResponsibilityId());
905     }
906 
907     public String toString() {
908         return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
909             .append("actionRequestId", actionRequestId)
910             .append("actionRequested", actionRequested)
911             .append("documentId", documentId)
912             .append("status", status)
913             .append("responsibilityId", responsibilityId)
914             .append("groupId", groupId)
915             .append("recipientTypeCd", recipientTypeCd)
916             .append("priority", priority)
917             .append("routeLevel", routeLevel)
918             .append("actionTakenId", actionTakenId)
919             .append("docVersion", docVersion)
920             .append("createDate", createDate)
921             .append("responsibilityDesc", responsibilityDesc)
922             .append("annotation", annotation)
923             .append("jrfVerNbr", jrfVerNbr)
924             .append("principalId", principalId)
925             .append("forceAction", forceAction)
926             .append("parentActionRequestId", parentActionRequestId)
927             .append("qualifiedRoleName", qualifiedRoleName)
928             .append("roleName", roleName)
929             .append("qualifiedRoleNameLabel", qualifiedRoleNameLabel)
930             .append("displayStatus", displayStatus)
931             .append("ruleBaseValuesId", ruleBaseValuesId)
932             .append("delegationType", delegationTypeCode)
933             .append("approvePolicy", approvePolicy)
934             .append("childrenRequests", childrenRequests == null ? null : childrenRequests.size())
935             .append("actionTaken", actionTaken)
936             .append("currentIndicator", currentIndicator)
937             .append("createDateString", createDateString)
938             .append("nodeInstance", nodeInstance).toString();
939     }
940 
941 	public String getRequestLabel() {
942 		return this.requestLabel;
943 	}
944 
945 	public void setRequestLabel(String requestLabel) {
946 		this.requestLabel = requestLabel;
947 	}
948 
949     public String getGroupName() {
950         return KimApiServiceLocator.getGroupService().getGroup(this.groupId).getName();
951     }
952 
953 	/**
954 	 * @return the resolveResponsibility
955 	 */
956 	public boolean getResolveResponsibility() {
957 		return this.resolveResponsibility;
958 	}
959 
960 	/**
961 	 * @param resolveResponsibility the resolveResponsibility to set
962 	 */
963 	public void setResolveResponsibility(boolean resolveResponsibility) {
964 		this.resolveResponsibility = resolveResponsibility;
965 	}
966 
967 	public DocumentRouteHeaderValue getRouteHeader() {
968 		if (this.routeHeader == null && this.documentId != null) {
969 			this.routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(this.documentId);
970 		}
971 		return this.routeHeader;
972 	}
973 
974 	public void setRouteHeader(DocumentRouteHeaderValue routeHeader) {
975 		this.routeHeader = routeHeader;
976 	}
977 	
978 	public static ActionRequest to(ActionRequestValue actionRequestBo) {
979 		if (actionRequestBo == null) {
980 			return null;
981 		}
982 		return createActionRequestBuilder(actionRequestBo).build();
983 	}
984 	
985 	private static ActionRequest.Builder createActionRequestBuilder(ActionRequestValue actionRequestBo) {
986 		ActionRequest.Builder builder = ActionRequest.Builder.create(actionRequestBo.getActionRequestId(),
987 				ActionRequestType.fromCode(actionRequestBo.getActionRequested()),
988 				ActionRequestStatus.fromCode(actionRequestBo.getStatus()),
989 				actionRequestBo.getResponsibilityId(),
990 				actionRequestBo.getDocumentId(),
991 				RecipientType.fromCode(actionRequestBo.getRecipientTypeCd()));
992 		if (actionRequestBo.getActionTaken() != null) {
993 			builder.setActionTaken(ActionTaken.Builder.create(ActionTakenValue.to(actionRequestBo.getActionTaken())));
994 		}
995 		builder.setAnnotation(actionRequestBo.getAnnotation());
996 		builder.setCurrent(actionRequestBo.getCurrentIndicator().booleanValue());
997 		builder.setDateCreated(new DateTime(actionRequestBo.getCreateDate().getTime()));
998 		if (actionRequestBo.getDelegationType() != null) {
999 			builder.setDelegationType(actionRequestBo.getDelegationType());
1000 		}
1001 		builder.setForceAction(actionRequestBo.getForceAction().booleanValue());
1002 		builder.setGroupId(actionRequestBo.getGroupId());
1003 		builder.setNodeName(actionRequestBo.getPotentialNodeName());
1004 		if (actionRequestBo.getParentActionRequestId() != null) {
1005 			builder.setParentActionRequestId(actionRequestBo.getParentActionRequestId());
1006 		}
1007 		builder.setPrincipalId(actionRequestBo.getPrincipalId());
1008 		if (actionRequestBo.getPriority() == null) {
1009 			builder.setPriority(KewApiConstants.ACTION_REQUEST_DEFAULT_PRIORITY);
1010 		} else {
1011             builder.setPriority(actionRequestBo.getPriority().intValue());
1012         }
1013         if (actionRequestBo.getRouteLevel() == null ) {
1014             builder.setRouteLevel(0);
1015         } else {
1016             builder.setRouteLevel(actionRequestBo.getRouteLevel().intValue());
1017         }
1018 		builder.setQualifiedRoleName(actionRequestBo.getQualifiedRoleName());
1019 		builder.setQualifiedRoleNameLabel(actionRequestBo.getQualifiedRoleNameLabel());
1020 		builder.setRequestLabel(actionRequestBo.getRequestLabel());
1021 		if (!StringUtils.isBlank(actionRequestBo.getApprovePolicy())) {
1022 			builder.setRequestPolicy(ActionRequestPolicy.fromCode(actionRequestBo.getApprovePolicy()));
1023 		}
1024 		builder.setResponsibilityDescription(actionRequestBo.getResponsibilityDesc());
1025 		builder.setRoleName(actionRequestBo.getRoleName());
1026 		if (actionRequestBo.getNodeInstance() != null) {
1027 			builder.setRouteNodeInstanceId(actionRequestBo.getNodeInstance().getRouteNodeInstanceId());
1028 		}
1029 		
1030 		List<ActionRequest.Builder> childRequests = new ArrayList<ActionRequest.Builder>();
1031 		if (actionRequestBo.getChildrenRequests() != null) {
1032 			for (ActionRequestValue childActionRequestBo : actionRequestBo.getChildrenRequests()) {
1033 				childRequests.add(createActionRequestBuilder(childActionRequestBo));
1034 			}
1035 		}
1036 		builder.setChildRequests(childRequests);
1037 		return builder;
1038 	}
1039 	
1040     /**
1041      * TODO - this javadoc copied from DTOConverter, needs to be updated!
1042      * 
1043      * Converts an ActionRequestVO to an ActionRequest. The ActionRequestDTO passed in must be the root action request in the
1044      * graph, otherwise an IllegalArgumentException is thrown. This is to avoid potentially sticky issues with circular
1045      * references in the conversion. NOTE: This method's primary purpose is to convert ActionRequestVOs returned from a
1046      * RouteModule. Incidentally, the DTO's returned from the route module will be lacking some information (like the node
1047      * instance) so no attempts are made to convert this data since further initialization is handled by a higher level
1048      * component (namely ActionRequestService.initializeActionRequestGraph).
1049      */
1050     public static ActionRequestValue from(ActionRequest actionRequest) {
1051         return ActionRequestValue.from(actionRequest, null);
1052     }
1053     
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. 
1058      * @param routeNodeInstanceLoader a service that will provide routeNodeInstanceS based on their IDs.
1059      */
1060     public static ActionRequestValue from(ActionRequest actionRequest, 
1061             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1062         return convertActionRequest(actionRequest, null, routeNodeInstanceLoader);
1063     }
1064 
1065     private static ActionRequestValue convertActionRequest(ActionRequest actionRequest, ActionRequestValue parentActionRequestBo,
1066             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1067         if (actionRequest == null) {
1068             return null;
1069         }
1070         ActionRequestValue actionRequestBo = new ActionRequestFactory().createBlankActionRequest();
1071         populateActionRequest(actionRequestBo, actionRequest, routeNodeInstanceLoader);
1072         if (parentActionRequestBo != null) {
1073             actionRequestBo.setParentActionRequest(parentActionRequestBo);
1074             actionRequestBo.setParentActionRequestId(parentActionRequestBo.getActionRequestId());
1075         }
1076         if (actionRequest.getChildRequests() != null) {
1077             for (ActionRequest childRequest : actionRequest.getChildRequests()) {
1078                 actionRequestBo.getChildrenRequests().add(ActionRequestValue.convertActionRequest(childRequest, actionRequestBo, routeNodeInstanceLoader));
1079             }
1080         }
1081         return actionRequestBo;
1082     }
1083 
1084     /**
1085      * This method converts everything except for the parent and child requests
1086      */
1087     private static void populateActionRequest(ActionRequestValue actionRequestBo, ActionRequest actionRequest, 
1088             RouteNodeInstanceLoader routeNodeInstanceLoader) {
1089 
1090         actionRequestBo.setActionRequested(actionRequest.getActionRequested().getCode());
1091         if (!StringUtils.isBlank(actionRequest.getId())) {
1092             actionRequestBo.setActionRequestId(actionRequest.getId());
1093         }
1094         
1095         if (actionRequest.getActionTaken() != null) {
1096             // actionRequestBo.setActionTaken(ActionTakenValue.from(actionRequest.getActionTaken()));
1097             if (!StringUtils.isBlank(actionRequest.getActionTaken().getId())) {
1098                 actionRequestBo.setActionTakenId(actionRequest.getActionTaken().getId());
1099             }
1100         }
1101         actionRequestBo.setAnnotation(actionRequest.getAnnotation());
1102         if (actionRequest.getRequestPolicy() != null) {
1103             actionRequestBo.setApprovePolicy(actionRequest.getRequestPolicy().getCode());
1104         }
1105         actionRequestBo.setCreateDate(new Timestamp(actionRequest.getDateCreated().getMillis()));
1106         actionRequestBo.setCurrentIndicator(actionRequest.isCurrent());
1107         if (actionRequest.getDelegationType() != null) {
1108             actionRequestBo.setDelegationType(actionRequest.getDelegationType());
1109         }
1110         //actionRequestBo.setDocVersion(actionRequest.?);
1111         actionRequestBo.setForceAction(actionRequest.isForceAction());
1112         actionRequestBo.setPriority(actionRequest.getPriority());
1113         actionRequestBo.setRouteLevel(actionRequest.getRouteLevel());
1114         actionRequestBo.setQualifiedRoleName(actionRequest.getQualifiedRoleName());
1115         actionRequestBo.setQualifiedRoleNameLabel(actionRequest.getQualifiedRoleNameLabel());
1116         actionRequestBo.setRecipientTypeCd(actionRequest.getRecipientType().getCode());
1117         actionRequestBo.setResponsibilityDesc(actionRequest.getResponsibilityDescription());
1118         if (!StringUtils.isBlank(actionRequest.getResponsibilityId())) {
1119             actionRequestBo.setResponsibilityId(actionRequest.getResponsibilityId());
1120         }
1121         actionRequestBo.setRoleName(actionRequest.getRoleName());
1122         String documentId = actionRequest.getDocumentId();
1123         if (documentId != null) {
1124             actionRequestBo.setDocumentId(documentId);
1125             actionRequestBo.setRouteHeader(KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId));
1126         }
1127 
1128         actionRequestBo.setStatus(actionRequest.getStatus().getCode());
1129         actionRequestBo.setPrincipalId(actionRequest.getPrincipalId());
1130         actionRequestBo.setGroupId(actionRequest.getGroupId());
1131         
1132         if (routeNodeInstanceLoader != null && !StringUtils.isBlank(actionRequest.getRouteNodeInstanceId())) {
1133             actionRequestBo.setNodeInstance(routeNodeInstanceLoader.load(actionRequest.getRouteNodeInstanceId()));
1134         }
1135     }
1136     
1137 }