1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.routeheader;
17
18 import org.apache.commons.lang.ObjectUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.joda.time.DateTime;
22 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
23 import org.kuali.rice.core.api.exception.RiceRuntimeException;
24 import org.kuali.rice.kew.actionitem.ActionItem;
25 import org.kuali.rice.kew.actionlist.CustomActionListAttribute;
26 import org.kuali.rice.kew.actionlist.DefaultCustomActionListAttribute;
27 import org.kuali.rice.kew.actionrequest.ActionRequestFactory;
28 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
29 import org.kuali.rice.kew.actiontaken.ActionTakenValue;
30 import org.kuali.rice.kew.api.KewApiConstants;
31 import org.kuali.rice.kew.api.WorkflowRuntimeException;
32 import org.kuali.rice.kew.api.action.ActionType;
33 import org.kuali.rice.kew.api.document.Document;
34 import org.kuali.rice.kew.api.document.DocumentContract;
35 import org.kuali.rice.kew.api.document.DocumentStatus;
36 import org.kuali.rice.kew.api.document.DocumentUpdate;
37 import org.kuali.rice.kew.api.exception.InvalidActionTakenException;
38 import org.kuali.rice.kew.api.exception.ResourceUnavailableException;
39 import org.kuali.rice.kew.api.exception.WorkflowException;
40 import org.kuali.rice.kew.api.util.CodeTranslator;
41 import org.kuali.rice.kew.docsearch.DocumentSearchCriteriaEbo;
42 import org.kuali.rice.kew.doctype.ApplicationDocumentStatus;
43 import org.kuali.rice.kew.doctype.DocumentTypePolicy;
44 import org.kuali.rice.kew.doctype.bo.DocumentType;
45 import org.kuali.rice.kew.engine.CompatUtils;
46 import org.kuali.rice.kew.engine.node.Branch;
47 import org.kuali.rice.kew.engine.node.BranchState;
48 import org.kuali.rice.kew.engine.node.RouteNode;
49 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
50 import org.kuali.rice.kew.mail.CustomEmailAttribute;
51 import org.kuali.rice.kew.mail.CustomEmailAttributeImpl;
52 import org.kuali.rice.kew.notes.CustomNoteAttribute;
53 import org.kuali.rice.kew.notes.CustomNoteAttributeImpl;
54 import org.kuali.rice.kew.notes.Note;
55 import org.kuali.rice.kew.quicklinks.dao.impl.QuickLinksDAOJpa;
56 import org.kuali.rice.kew.routeheader.dao.impl.DocumentRouteHeaderDAOJpa;
57 import org.kuali.rice.kew.service.KEWServiceLocator;
58 import org.kuali.rice.kim.api.identity.Person;
59 import org.kuali.rice.kim.api.identity.principal.Principal;
60 import org.kuali.rice.krad.bo.DataObjectBase;
61 import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
62
63 import javax.persistence.Cacheable;
64 import javax.persistence.CascadeType;
65 import javax.persistence.Column;
66 import javax.persistence.Entity;
67 import javax.persistence.GeneratedValue;
68 import javax.persistence.Id;
69 import javax.persistence.JoinColumn;
70 import javax.persistence.JoinTable;
71 import javax.persistence.ManyToMany;
72 import javax.persistence.NamedAttributeNode;
73 import javax.persistence.NamedEntityGraph;
74 import javax.persistence.NamedEntityGraphs;
75 import javax.persistence.NamedQueries;
76 import javax.persistence.NamedQuery;
77 import javax.persistence.OneToMany;
78 import javax.persistence.OrderBy;
79 import javax.persistence.Table;
80 import javax.persistence.Transient;
81
82 import java.sql.Timestamp;
83 import java.util.ArrayList;
84 import java.util.HashMap;
85 import java.util.Iterator;
86 import java.util.List;
87 import java.util.Map;
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 @Entity
126 @Table(name="KREW_DOC_HDR_T")
127 @NamedQueries({
128 @NamedQuery(name=QuickLinksDAOJpa.FIND_WATCHED_DOCUMENTS_BY_INITIATOR_WORKFLOW_ID_NAME,
129 query= QuickLinksDAOJpa.FIND_WATCHED_DOCUMENTS_BY_INITIATOR_WORKFLOW_ID_QUERY),
130 @NamedQuery(name= DocumentRouteHeaderDAOJpa.GET_APP_DOC_ID_NAME, query=
131 DocumentRouteHeaderDAOJpa.GET_APP_DOC_ID_QUERY),
132 @NamedQuery(name=DocumentRouteHeaderDAOJpa.GET_APP_DOC_STATUS_NAME, query=
133 DocumentRouteHeaderDAOJpa.GET_APP_DOC_STATUS_QUERY),
134 @NamedQuery(name=DocumentRouteHeaderDAOJpa.GET_DOCUMENT_HEADERS_NAME, query=
135 DocumentRouteHeaderDAOJpa.GET_DOCUMENT_HEADERS_QUERY),
136 @NamedQuery(name=DocumentRouteHeaderDAOJpa.GET_DOCUMENT_STATUS_NAME, query=
137 DocumentRouteHeaderDAOJpa.GET_DOCUMENT_STATUS_QUERY),
138 @NamedQuery(name=DocumentRouteHeaderDAOJpa.GET_DOCUMENT_ID_BY_DOC_TYPE_APP_ID_NAME, query =
139 DocumentRouteHeaderDAOJpa.GET_DOCUMENT_ID_BY_DOC_TYPE_APP_ID_QUERY)
140 })
141 @NamedEntityGraphs({
142 @NamedEntityGraph(name="DocumentRouteHeaderValue.ActionListAttributesOnly"
143 ,attributeNodes={
144 @NamedAttributeNode("approvedDate")
145 ,@NamedAttributeNode("createDate")
146 ,@NamedAttributeNode("docRouteStatus")
147 ,@NamedAttributeNode("initiatorWorkflowId")
148 ,@NamedAttributeNode("appDocStatus")
149 ,@NamedAttributeNode("documentId")
150 ,@NamedAttributeNode("docRouteLevel")
151 ,@NamedAttributeNode("documentTypeId")
152 ,@NamedAttributeNode("docVersion")
153 })
154 })
155 @Cacheable(false)
156 public class DocumentRouteHeaderValue extends DataObjectBase implements DocumentContract, DocumentSearchCriteriaEbo {
157
158 private static final long serialVersionUID = -4700736340527913220L;
159 private static final Logger LOG = Logger.getLogger(DocumentRouteHeaderValue.class);
160
161 private static final String TERMINAL = "";
162 private static final boolean FINAL_STATE = true;
163 protected static final HashMap<String,String> legalActions;
164 protected static final HashMap<String,String> stateTransitionMap;
165 static {
166 stateTransitionMap = new HashMap<String,String>();
167 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_INITIATED_CD, KewApiConstants.ROUTE_HEADER_SAVED_CD + KewApiConstants.ROUTE_HEADER_ENROUTE_CD + KewApiConstants.ROUTE_HEADER_CANCEL_CD);
168
169 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_SAVED_CD, KewApiConstants.ROUTE_HEADER_SAVED_CD + KewApiConstants.ROUTE_HEADER_ENROUTE_CD + KewApiConstants.ROUTE_HEADER_CANCEL_CD + KewApiConstants.ROUTE_HEADER_PROCESSED_CD);
170
171 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_ENROUTE_CD, KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD +
172 KewApiConstants.ROUTE_HEADER_CANCEL_CD + KewApiConstants.ROUTE_HEADER_PROCESSED_CD + KewApiConstants.ROUTE_HEADER_EXCEPTION_CD + KewApiConstants.ROUTE_HEADER_SAVED_CD
173 + DocumentStatus.RECALLED.getCode());
174 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD, TERMINAL);
175 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_CANCEL_CD, TERMINAL);
176 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_FINAL_CD, TERMINAL);
177 stateTransitionMap.put(DocumentStatus.RECALLED.getCode(), TERMINAL);
178 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_EXCEPTION_CD, KewApiConstants.ROUTE_HEADER_EXCEPTION_CD + KewApiConstants.ROUTE_HEADER_ENROUTE_CD + KewApiConstants.ROUTE_HEADER_CANCEL_CD + KewApiConstants.ROUTE_HEADER_PROCESSED_CD + KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD + KewApiConstants.ROUTE_HEADER_SAVED_CD);
179 stateTransitionMap.put(KewApiConstants.ROUTE_HEADER_PROCESSED_CD, KewApiConstants.ROUTE_HEADER_FINAL_CD + KewApiConstants.ROUTE_HEADER_PROCESSED_CD);
180
181 legalActions = new HashMap<String,String>();
182 legalActions.put(KewApiConstants.ROUTE_HEADER_INITIATED_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_SAVED_CD + KewApiConstants.ACTION_TAKEN_COMPLETED_CD + KewApiConstants.ACTION_TAKEN_ROUTED_CD + KewApiConstants.ACTION_TAKEN_CANCELED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD + KewApiConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + KewApiConstants.ACTION_TAKEN_MOVE_CD);
183 legalActions.put(KewApiConstants.ROUTE_HEADER_SAVED_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_SAVED_CD + KewApiConstants.ACTION_TAKEN_COMPLETED_CD + KewApiConstants.ACTION_TAKEN_ROUTED_CD + KewApiConstants.ACTION_TAKEN_APPROVED_CD + KewApiConstants.ACTION_TAKEN_CANCELED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD + KewApiConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + KewApiConstants.ACTION_TAKEN_MOVE_CD);
184
185
186
187 legalActions.put(KewApiConstants.ROUTE_HEADER_ENROUTE_CD, KewApiConstants.ACTION_TAKEN_APPROVED_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ADHOC_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD + KewApiConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + KewApiConstants.ACTION_TAKEN_CANCELED_CD + KewApiConstants.ACTION_TAKEN_COMPLETED_CD + KewApiConstants.ACTION_TAKEN_DENIED_CD + KewApiConstants.ACTION_TAKEN_SU_APPROVED_CD + KewApiConstants.ACTION_TAKEN_SU_CANCELED_CD + KewApiConstants.ACTION_TAKEN_SU_DISAPPROVED_CD + KewApiConstants.ACTION_TAKEN_SU_ROUTE_LEVEL_APPROVED_CD + KewApiConstants.ACTION_TAKEN_RETURNED_TO_PREVIOUS_CD + KewApiConstants.ACTION_TAKEN_SU_RETURNED_TO_PREVIOUS_CD + KewApiConstants.ACTION_TAKEN_MOVE_CD + ActionType.RECALL.getCode());
188
189
190
191 legalActions.put(KewApiConstants.ROUTE_HEADER_EXCEPTION_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD + KewApiConstants.ACTION_TAKEN_APPROVED_CD + KewApiConstants.ACTION_TAKEN_BLANKET_APPROVE_CD + KewApiConstants.ACTION_TAKEN_CANCELED_CD + KewApiConstants.ACTION_TAKEN_COMPLETED_CD + KewApiConstants.ACTION_TAKEN_DENIED_CD + KewApiConstants.ACTION_TAKEN_SU_APPROVED_CD + KewApiConstants.ACTION_TAKEN_SU_CANCELED_CD + KewApiConstants.ACTION_TAKEN_SU_DISAPPROVED_CD + KewApiConstants.ACTION_TAKEN_SU_ROUTE_LEVEL_APPROVED_CD + KewApiConstants.ACTION_TAKEN_RETURNED_TO_PREVIOUS_CD + KewApiConstants.ACTION_TAKEN_SU_RETURNED_TO_PREVIOUS_CD + KewApiConstants.ACTION_TAKEN_MOVE_CD);
192 legalActions.put(KewApiConstants.ROUTE_HEADER_FINAL_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD);
193 legalActions.put(KewApiConstants.ROUTE_HEADER_CANCEL_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD);
194 legalActions.put(KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD);
195 legalActions.put(KewApiConstants.ROUTE_HEADER_PROCESSED_CD, KewApiConstants.ACTION_TAKEN_FYI_CD + KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD + KewApiConstants.ACTION_TAKEN_ADHOC_REVOKED_CD);
196 legalActions.put(DocumentStatus.RECALLED.getCode(), TERMINAL);
197 }
198
199 public static final String CURRENT_ROUTE_NODE_NAME_DELIMITER = ", ";
200
201 @Id
202 @GeneratedValue(generator = "KREW_DOC_HDR_S")
203 @PortableSequenceGenerator(name = "KREW_DOC_HDR_S")
204 @Column(name = "DOC_HDR_ID", nullable = false)
205 private String documentId;
206
207 @Column(name = "DOC_TYP_ID")
208 private String documentTypeId;
209
210 @Column(name = "DOC_HDR_STAT_CD", nullable = false)
211 private String docRouteStatus;
212
213 @Column(name = "RTE_LVL", nullable = false)
214 private Integer docRouteLevel;
215
216 @Column(name = "STAT_MDFN_DT", nullable = false)
217 private Timestamp dateModified;
218
219 @Column(name = "CRTE_DT", nullable = false)
220 private Timestamp createDate;
221
222 @Column(name = "APRV_DT")
223 private Timestamp approvedDate;
224
225 @Column(name = "FNL_DT")
226 private Timestamp finalizedDate;
227
228 @Column(name = "TTL")
229 private String docTitle;
230
231 @Column(name = "APP_DOC_ID")
232 private String appDocId;
233
234 @Column(name = "DOC_VER_NBR", nullable = false)
235 private Integer docVersion = new Integer(KewApiConstants.DocumentContentVersions.NODAL);
236
237 @Column(name = "INITR_PRNCPL_ID", nullable = false)
238 private String initiatorWorkflowId;
239
240 @Column(name = "RTE_PRNCPL_ID")
241 private String routedByUserWorkflowId;
242
243 @Column(name = "RTE_STAT_MDFN_DT")
244 private Timestamp routeStatusDate;
245
246 @Column(name = "APP_DOC_STAT")
247 private String appDocStatus;
248
249 @Column(name = "APP_DOC_STAT_MDFN_DT")
250 private Timestamp appDocStatusDate;
251
252 @ManyToMany(cascade = CascadeType.ALL)
253 @JoinTable(name = "KREW_INIT_RTE_NODE_INSTN_T", joinColumns = @JoinColumn(name = "DOC_HDR_ID"), inverseJoinColumns = @JoinColumn(name = "RTE_NODE_INSTN_ID"))
254 private List<RouteNodeInstance> initialRouteNodeInstances = new ArrayList<RouteNodeInstance>();
255
256
257
258
259
260
261 @OneToMany(cascade = CascadeType.ALL, mappedBy = "documentRouteHeaderValue")
262 @OrderBy("statusTransitionId ASC")
263 private List<DocumentStatusTransition> appDocStatusHistory = new ArrayList<DocumentStatusTransition>();
264
265 @OneToMany(cascade = CascadeType.ALL)
266 @JoinColumn(name = "DOC_HDR_ID")
267 @OrderBy("noteId ASC")
268 private List<Note> notes = new ArrayList<Note>();
269
270 @Transient private DocumentRouteHeaderValueContent documentContent;
271 @Transient private boolean routingReport = false;
272 @Transient private List<ActionRequestValue> simulatedActionRequests;
273
274 public Principal getInitiatorPrincipal() {
275
276 if ( StringUtils.isBlank( getInitiatorWorkflowId() ) ) {
277 return null;
278 }
279 return KEWServiceLocator.getIdentityHelperService().getPrincipal(getInitiatorWorkflowId());
280 }
281
282 public Principal getRoutedByPrincipal()
283 {
284 if (getRoutedByUserWorkflowId() == null) {
285 return null;
286 }
287 return KEWServiceLocator.getIdentityHelperService().getPrincipal(getRoutedByUserWorkflowId());
288 }
289
290 public String getInitiatorDisplayName() {
291 try {
292 Person person = KEWServiceLocator.getIdentityHelperService().getPerson(getInitiatorWorkflowId());
293 return person.getName();
294 } catch (RiceIllegalArgumentException e) {
295 return getInitiatorWorkflowId();
296 }
297 }
298
299 public String getRoutedByDisplayName() {
300 String routedByUserWorkflowId = getRoutedByUserWorkflowId();
301 if (StringUtils.isBlank(routedByUserWorkflowId)) {
302 return "";
303 }
304 return KEWServiceLocator.getIdentityHelperService().getPerson(getRoutedByUserWorkflowId()).getName();
305 }
306
307 public String getCurrentRouteLevelName() {
308 String name = "Not Found";
309
310 if(routingReport){
311 name = "Routing Report";
312 } else if (CompatUtils.isRouteLevelDocument(this)) {
313 int routeLevelInt = getDocRouteLevel().intValue();
314 if ( LOG.isInfoEnabled() ) {
315 LOG.info("Getting current route level name for a Route level document: " + routeLevelInt+CURRENT_ROUTE_NODE_NAME_DELIMITER+documentId);
316 }
317 List<RouteNode> routeLevelNodes = CompatUtils.getRouteLevelCompatibleNodeList(getDocumentType());
318 if ( LOG.isInfoEnabled() ) {
319 LOG.info("Route level compatible node list has " + routeLevelNodes.size() + " nodes");
320 }
321 if (routeLevelInt < routeLevelNodes.size()) {
322 name = routeLevelNodes.get(routeLevelInt).getRouteNodeName();
323 }
324 } else {
325 List<String> currentNodeNames = getCurrentNodeNames();
326 name = StringUtils.join(currentNodeNames, CURRENT_ROUTE_NODE_NAME_DELIMITER);
327 }
328 return name;
329 }
330
331 public List<String> getCurrentNodeNames() {
332 return KEWServiceLocator.getRouteNodeService().getCurrentRouteNodeNames(getDocumentId());
333 }
334
335 public String getRouteStatusLabel() {
336 return CodeTranslator.getRouteStatusLabel(getDocRouteStatus());
337 }
338
339 public String getDocRouteStatusLabel() {
340 return CodeTranslator.getRouteStatusLabel(getDocRouteStatus());
341 }
342
343
344
345
346
347
348
349
350 public String getDocStatusPolicy() {
351 return getDocumentType().getDocumentStatusPolicy().getPolicyStringValue();
352 }
353
354 public List<ActionItem> getActionItems() {
355 return (List<ActionItem>) KEWServiceLocator.getActionListService().findByDocumentId(documentId);
356 }
357
358 public List<ActionTakenValue> getActionsTaken() {
359 return KEWServiceLocator.getActionTakenService().findByDocumentIdIgnoreCurrentInd(documentId);
360 }
361
362 public List<ActionRequestValue> getActionRequests() {
363 if (this.simulatedActionRequests == null || this.simulatedActionRequests.isEmpty()) {
364 return KEWServiceLocator.getActionRequestService().findByDocumentIdIgnoreCurrentInd(documentId);
365 } else {
366 return this.simulatedActionRequests;
367 }
368 }
369
370 public List<ActionRequestValue> getSimulatedActionRequests() {
371 if (this.simulatedActionRequests == null) {
372 this.simulatedActionRequests = new ArrayList<ActionRequestValue>();
373 }
374 return this.simulatedActionRequests;
375 }
376
377 public void setSimulatedActionRequests(List<ActionRequestValue> simulatedActionRequests) {
378 this.simulatedActionRequests = simulatedActionRequests;
379 }
380
381 public DocumentType getDocumentType() {
382 return KEWServiceLocator.getDocumentTypeService().findById(getDocumentTypeId());
383 }
384
385 public java.lang.String getAppDocId() {
386 return appDocId;
387 }
388
389 public void setAppDocId(java.lang.String appDocId) {
390 this.appDocId = appDocId;
391 }
392
393 public java.sql.Timestamp getApprovedDate() {
394 return approvedDate;
395 }
396
397 public void setApprovedDate(java.sql.Timestamp approvedDate) {
398 this.approvedDate = approvedDate;
399 }
400
401 public java.sql.Timestamp getCreateDate() {
402 return createDate;
403 }
404
405 public void setCreateDate(java.sql.Timestamp createDate) {
406 this.createDate = createDate;
407 }
408
409 public java.lang.String getDocContent() {
410 return getDocumentContent().getDocumentContent();
411 }
412
413 public void setDocContent(java.lang.String docContent) {
414 DocumentRouteHeaderValueContent content = getDocumentContent();
415 content.setDocumentContent(docContent);
416 }
417
418 public java.lang.Integer getDocRouteLevel() {
419 return docRouteLevel;
420 }
421
422 public void setDocRouteLevel(java.lang.Integer docRouteLevel) {
423 this.docRouteLevel = docRouteLevel;
424 }
425
426 public java.lang.String getDocRouteStatus() {
427 return docRouteStatus;
428 }
429
430 public void setDocRouteStatus(java.lang.String docRouteStatus) {
431 this.docRouteStatus = docRouteStatus;
432 }
433
434 public java.lang.String getDocTitle() {
435 return docTitle;
436 }
437
438 public void setDocTitle(java.lang.String docTitle) {
439 this.docTitle = docTitle;
440 }
441
442 @Override
443 public String getDocumentTypeId() {
444 return documentTypeId;
445 }
446
447 public void setDocumentTypeId(String documentTypeId) {
448 this.documentTypeId = documentTypeId;
449 }
450
451 public java.lang.Integer getDocVersion() {
452 return docVersion;
453 }
454
455 public void setDocVersion(java.lang.Integer docVersion) {
456 this.docVersion = docVersion;
457 }
458
459 public java.sql.Timestamp getFinalizedDate() {
460 return finalizedDate;
461 }
462
463 public void setFinalizedDate(java.sql.Timestamp finalizedDate) {
464 this.finalizedDate = finalizedDate;
465 }
466
467 public java.lang.String getInitiatorWorkflowId() {
468 return initiatorWorkflowId;
469 }
470
471 public void setInitiatorWorkflowId(java.lang.String initiatorWorkflowId) {
472 this.initiatorWorkflowId = initiatorWorkflowId;
473 }
474
475 public java.lang.String getRoutedByUserWorkflowId() {
476 if ( (isEnroute()) && (StringUtils.isBlank(routedByUserWorkflowId)) ) {
477 return initiatorWorkflowId;
478 }
479 return routedByUserWorkflowId;
480 }
481
482 public void setRoutedByUserWorkflowId(java.lang.String routedByUserWorkflowId) {
483 this.routedByUserWorkflowId = routedByUserWorkflowId;
484 }
485
486 @Override
487 public String getDocumentId() {
488 return documentId;
489 }
490
491 public void setDocumentId(java.lang.String documentId) {
492 this.documentId = documentId;
493 }
494
495 public java.sql.Timestamp getRouteStatusDate() {
496 return routeStatusDate;
497 }
498
499 public void setRouteStatusDate(java.sql.Timestamp routeStatusDate) {
500 this.routeStatusDate = routeStatusDate;
501 }
502
503 public java.sql.Timestamp getDateModified() {
504 return dateModified;
505 }
506
507 public void setDateModified(java.sql.Timestamp dateModified) {
508 this.dateModified = dateModified;
509 }
510
511
512
513
514
515
516
517
518
519
520
521
522 public java.lang.String getAppDocStatus() {
523 if ( StringUtils.isBlank(appDocStatus) ){
524 return KewApiConstants.UNKNOWN_STATUS;
525 }
526 return appDocStatus;
527 }
528
529 public void setAppDocStatus(java.lang.String appDocStatus){
530 this.appDocStatus = appDocStatus;
531 }
532
533
534
535
536
537
538
539 public String getCombinedStatus(){
540 String routeStatus = getRouteStatusLabel();
541 String appStatus = getAppDocStatus();
542 if ( StringUtils.isNotEmpty(routeStatus)){
543 if (StringUtils.isNotEmpty(appStatus)){
544 routeStatus += ", "+appStatus;
545 }
546 } else {
547 return appStatus;
548 }
549 return routeStatus;
550 }
551
552
553
554
555
556
557
558
559
560
561 public void updateAppDocStatus(java.lang.String appDocStatus) throws WorkflowRuntimeException{
562
563 if (appDocStatus != null && appDocStatus.length() > 0 && !appDocStatus.equalsIgnoreCase(this.appDocStatus)){
564 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findById(this.getDocumentTypeId());
565 if (documentType.getValidApplicationStatuses() != null && documentType.getValidApplicationStatuses().size() > 0){
566 Iterator<ApplicationDocumentStatus> iter = documentType.getValidApplicationStatuses().iterator();
567 boolean statusValidated = false;
568 while (iter.hasNext())
569 {
570 ApplicationDocumentStatus myAppDocStat = iter.next();
571 if (appDocStatus.compareToIgnoreCase(myAppDocStat.getStatusName()) == 0)
572 {
573 statusValidated = true;
574 break;
575 }
576 }
577 if (!statusValidated){
578 WorkflowRuntimeException xpee = new WorkflowRuntimeException("AppDocStatus value " + appDocStatus + " not allowable.");
579 LOG.error("Error validating nextAppDocStatus name: " + appDocStatus + " against acceptable values.", xpee);
580 throw xpee;
581 }
582 }
583
584
585 String oldStatus = this.appDocStatus;
586 this.appDocStatus = appDocStatus;
587
588
589 setAppDocStatusDate(new Timestamp(System.currentTimeMillis()));
590
591
592 this.appDocStatusHistory.add(new DocumentStatusTransition(documentId, oldStatus, appDocStatus));
593 }
594
595 }
596
597
598 public java.sql.Timestamp getAppDocStatusDate() {
599 return appDocStatusDate;
600 }
601
602 public void setAppDocStatusDate(java.sql.Timestamp appDocStatusDate) {
603 this.appDocStatusDate = appDocStatusDate;
604 }
605
606 public Object copy(boolean preserveKeys) {
607 throw new UnsupportedOperationException("The copy method is deprecated and unimplemented!");
608 }
609
610
611
612
613 public boolean isStateInitiated() {
614 return KewApiConstants.ROUTE_HEADER_INITIATED_CD.equals(docRouteStatus);
615 }
616
617
618
619
620 public boolean isStateSaved() {
621 return KewApiConstants.ROUTE_HEADER_SAVED_CD.equals(docRouteStatus);
622 }
623
624
625
626
627 public boolean isRouted() {
628 return !(isStateInitiated() || isStateSaved());
629 }
630
631 public boolean isInException() {
632 return KewApiConstants.ROUTE_HEADER_EXCEPTION_CD.equals(docRouteStatus);
633 }
634
635 public boolean isDisaproved() {
636 return KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD.equals(docRouteStatus);
637 }
638
639 public boolean isCanceled() {
640 return KewApiConstants.ROUTE_HEADER_CANCEL_CD.equals(docRouteStatus);
641 }
642
643 public boolean isFinal() {
644 return KewApiConstants.ROUTE_HEADER_FINAL_CD.equals(docRouteStatus);
645 }
646
647 public boolean isEnroute() {
648 return KewApiConstants.ROUTE_HEADER_ENROUTE_CD.equals(docRouteStatus);
649 }
650
651
652
653
654 public boolean isProcessed() {
655 return KewApiConstants.ROUTE_HEADER_PROCESSED_CD.equals(docRouteStatus);
656 }
657
658 public boolean isRoutable() {
659 return KewApiConstants.ROUTE_HEADER_ENROUTE_CD.equals(docRouteStatus) ||
660
661 KewApiConstants.ROUTE_HEADER_SAVED_CD.equals(docRouteStatus) ||
662 KewApiConstants.ROUTE_HEADER_PROCESSED_CD.equals(docRouteStatus);
663 }
664
665
666
667
668
669
670
671
672
673 public boolean isValidActionToTake(String actionCd) {
674 String actions = legalActions.get(docRouteStatus);
675 return actions.contains(actionCd);
676 }
677
678 public boolean isValidStatusChange(String newStatus) {
679 return stateTransitionMap.get(getDocRouteStatus()).contains(newStatus);
680 }
681
682 public void setRouteStatus(String newStatus, boolean finalState) throws InvalidActionTakenException {
683 if (newStatus != getDocRouteStatus()) {
684
685 setRouteStatusDate(new Timestamp(System.currentTimeMillis()));
686 }
687 if (stateTransitionMap.get(getDocRouteStatus()).contains(newStatus)) {
688 LOG.debug("changing status");
689 setDocRouteStatus(newStatus);
690 } else {
691 LOG.debug("unable to change status");
692 throw new InvalidActionTakenException("Document status " + CodeTranslator.getRouteStatusLabel(getDocRouteStatus()) + " cannot transition to status " + CodeTranslator
693 .getRouteStatusLabel(newStatus));
694 }
695 setDateModified(new Timestamp(System.currentTimeMillis()));
696 if (finalState) {
697 LOG.debug("setting final timeStamp");
698 setFinalizedDate(new Timestamp(System.currentTimeMillis()));
699 }
700 }
701
702
703
704
705
706
707
708 public void markDocumentProcessed() throws InvalidActionTakenException {
709 if ( LOG.isDebugEnabled() ) {
710 LOG.debug(this + " marked processed");
711 }
712 setRouteStatus(KewApiConstants.ROUTE_HEADER_PROCESSED_CD, !FINAL_STATE);
713 }
714
715
716
717
718
719
720
721 public void markDocumentCanceled() throws InvalidActionTakenException {
722 if ( LOG.isDebugEnabled() ) {
723 LOG.debug(this + " marked canceled");
724 }
725 setRouteStatus(KewApiConstants.ROUTE_HEADER_CANCEL_CD, FINAL_STATE);
726 }
727
728
729
730
731
732
733
734 public void markDocumentRecalled() throws InvalidActionTakenException {
735 if ( LOG.isDebugEnabled() ) {
736 LOG.debug(this + " marked recalled");
737 }
738 setRouteStatus(DocumentStatus.RECALLED.getCode(), FINAL_STATE);
739 }
740
741
742
743
744
745
746
747 public void markDocumentDisapproved() throws InvalidActionTakenException {
748 if ( LOG.isDebugEnabled() ) {
749 LOG.debug(this + " marked disapproved");
750 }
751 setRouteStatus(KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD, FINAL_STATE);
752 }
753
754
755
756
757
758
759
760 public void markDocumentSaved() throws InvalidActionTakenException {
761 if ( LOG.isDebugEnabled() ) {
762 LOG.debug(this + " marked saved");
763 }
764 setRouteStatus(KewApiConstants.ROUTE_HEADER_SAVED_CD, !FINAL_STATE);
765 }
766
767
768
769
770
771
772
773 public void markDocumentInException() throws InvalidActionTakenException {
774 if ( LOG.isDebugEnabled() ) {
775 LOG.debug(this + " marked in exception");
776 }
777 setRouteStatus(KewApiConstants.ROUTE_HEADER_EXCEPTION_CD, !FINAL_STATE);
778 }
779
780
781
782
783
784
785
786 public void markDocumentEnroute() throws InvalidActionTakenException {
787 if ( LOG.isDebugEnabled() ) {
788 LOG.debug(this + " marked enroute");
789 }
790 setRouteStatus(KewApiConstants.ROUTE_HEADER_ENROUTE_CD, !FINAL_STATE);
791 }
792
793
794
795
796
797
798
799 public void markDocumentFinalized() throws InvalidActionTakenException {
800 if ( LOG.isDebugEnabled() ) {
801 LOG.debug(this + " marked finalized");
802 }
803 setRouteStatus(KewApiConstants.ROUTE_HEADER_FINAL_CD, FINAL_STATE);
804 }
805
806
807
808
809
810
811 public void setRouteHeaderData(Document routeHeaderVO) throws WorkflowException {
812 if (!ObjectUtils.equals(getDocTitle(), routeHeaderVO.getTitle())) {
813 KEWServiceLocator.getActionListService().updateActionItemsForTitleChange(getDocumentId(), routeHeaderVO.getTitle());
814 }
815 setDocTitle(routeHeaderVO.getTitle());
816 setAppDocId(routeHeaderVO.getApplicationDocumentId());
817 setDateModified(new Timestamp(System.currentTimeMillis()));
818 updateAppDocStatus(routeHeaderVO.getApplicationDocumentStatus());
819
820
821 for (Map.Entry<String, String> kvp : routeHeaderVO.getVariables().entrySet()) {
822 setVariable(kvp.getKey(), kvp.getValue());
823 }
824 }
825
826 public void applyDocumentUpdate(DocumentUpdate documentUpdate) {
827 if (documentUpdate != null) {
828 String thisDocTitle = getDocTitle() == null ? "" : getDocTitle();
829 String updateDocTitle = documentUpdate.getTitle() == null ? "" : documentUpdate.getTitle();
830 if (!StringUtils.equals(thisDocTitle, updateDocTitle)) {
831 KEWServiceLocator.getActionListService().updateActionItemsForTitleChange(getDocumentId(), documentUpdate.getTitle());
832 }
833 setDocTitle(updateDocTitle);
834 setAppDocId(documentUpdate.getApplicationDocumentId());
835 setDateModified(new Timestamp(System.currentTimeMillis()));
836 updateAppDocStatus(documentUpdate.getApplicationDocumentStatus());
837 List<String> dirtyFields = documentUpdate.getDirtyFields();
838 LOG.debug("Applying document update for document " + this.getDocumentId() + " dirtyFields = " + dirtyFields);
839 if(dirtyFields == null || dirtyFields.contains("title")) {
840 setDocTitle(updateDocTitle);
841 }
842 if(dirtyFields == null || dirtyFields.contains("applicationDocumentId")) {
843 setAppDocId(documentUpdate.getApplicationDocumentId());
844 }
845 setDateModified(new Timestamp(System.currentTimeMillis()));
846 if(dirtyFields == null || dirtyFields.contains("applicationDocumentStatus")) {
847 updateAppDocStatus(documentUpdate.getApplicationDocumentStatus());
848 }
849
850 Map<String, String> variables = documentUpdate.getVariables();
851 for (String variableName : variables.keySet()) {
852 setVariable(variableName, variables.get(variableName));
853 }
854
855 }
856 }
857
858
859
860
861
862 public Branch getRootBranch() {
863 if (!this.initialRouteNodeInstances.isEmpty()) {
864 return getInitialRouteNodeInstance(0).getBranch();
865 }
866 return null;
867 }
868
869
870
871
872
873 private BranchState findVariable(String name) {
874 Branch rootBranch = getRootBranch();
875 if (rootBranch != null) {
876 List<BranchState> branchState = rootBranch.getBranchState();
877 Iterator<BranchState> it = branchState.iterator();
878 while (it.hasNext()) {
879 BranchState state = it.next();
880 if (ObjectUtils.equals(state.getKey(), BranchState.VARIABLE_PREFIX + name)) {
881 return state;
882 }
883 }
884 }
885 return null;
886 }
887
888
889
890
891
892
893 public String getVariable(String name) {
894 BranchState state = findVariable(name);
895 if (state == null) {
896 if ( LOG.isDebugEnabled() ) {
897 LOG.debug("Variable not found: '" + name + "'");
898 }
899 return null;
900 }
901 return state.getValue();
902 }
903
904 public void removeVariableThatContains(String name) {
905 List<BranchState> statesToRemove = new ArrayList<BranchState>();
906 for (BranchState state : this.getRootBranchState()) {
907 if (state.getKey().contains(name)) {
908 statesToRemove.add(state);
909 }
910 }
911 this.getRootBranchState().removeAll(statesToRemove);
912 }
913
914
915
916
917
918
919 public void setVariable(String name, String value) {
920 BranchState state = findVariable(name);
921 Branch rootBranch = getRootBranch();
922 if (rootBranch != null) {
923 List<BranchState> branchState = rootBranch.getBranchState();
924 if (state == null) {
925 if (value == null) {
926 if ( LOG.isDebugEnabled() ) {
927 LOG.debug("set non existent variable '" + name + "' to null value");
928 }
929 return;
930 }
931 LOG.debug("Adding branch state: '" + name + "'='" + value + "'");
932 state = new BranchState();
933 state.setBranch(rootBranch);
934 state.setKey(BranchState.VARIABLE_PREFIX + name);
935 state.setValue(value);
936 rootBranch.addBranchState(state);
937 } else {
938 if (value == null) {
939 if ( LOG.isDebugEnabled() ) {
940 LOG.debug("Removing value: " + state.getKey() + "=" + state.getValue());
941 }
942 branchState.remove(state);
943 } else {
944 if ( LOG.isDebugEnabled() ) {
945 LOG.debug("Setting value of variable '" + name + "' to '" + value + "'");
946 }
947 state.setValue(value);
948 }
949 }
950 }
951 }
952
953 public List<BranchState> getRootBranchState() {
954 if (this.getRootBranch() != null) {
955 return this.getRootBranch().getBranchState();
956 }
957 return null;
958 }
959
960 public CustomActionListAttribute getCustomActionListAttribute() throws WorkflowException {
961 CustomActionListAttribute customActionListAttribute = null;
962 if (this.getDocumentType() != null) {
963 customActionListAttribute = this.getDocumentType().getCustomActionListAttribute();
964 if (customActionListAttribute != null) {
965 return customActionListAttribute;
966 }
967 }
968 customActionListAttribute = new DefaultCustomActionListAttribute();
969 return customActionListAttribute;
970 }
971
972 public CustomEmailAttribute getCustomEmailAttribute() throws WorkflowException {
973 CustomEmailAttribute customEmailAttribute = null;
974 try {
975 if (this.getDocumentType() != null) {
976 customEmailAttribute = this.getDocumentType().getCustomEmailAttribute();
977 if (customEmailAttribute != null) {
978 customEmailAttribute.setRouteHeaderVO(DocumentRouteHeaderValue.to(this));
979 return customEmailAttribute;
980 }
981 }
982 } catch (Exception e) {
983 LOG.warn("Error in retrieving custom email attribute", e);
984 }
985 customEmailAttribute = new CustomEmailAttributeImpl();
986 customEmailAttribute.setRouteHeaderVO(DocumentRouteHeaderValue.to(this));
987 return customEmailAttribute;
988 }
989
990 public CustomNoteAttribute getCustomNoteAttribute() throws WorkflowException
991 {
992 CustomNoteAttribute customNoteAttribute = null;
993 try {
994 if (this.getDocumentType() != null) {
995 customNoteAttribute = this.getDocumentType().getCustomNoteAttribute();
996 if (customNoteAttribute != null) {
997 customNoteAttribute.setRouteHeaderVO(DocumentRouteHeaderValue.to(this));
998 return customNoteAttribute;
999 }
1000 }
1001 } catch (Exception e) {
1002 LOG.warn("Error in retrieving custom note attribute", e);
1003 }
1004 customNoteAttribute = new CustomNoteAttributeImpl();
1005 customNoteAttribute.setRouteHeaderVO(DocumentRouteHeaderValue.to(this));
1006 return customNoteAttribute;
1007 }
1008
1009 public ActionRequestValue getDocActionRequest(int index) {
1010 List<ActionRequestValue> actionRequests = getActionRequests();
1011 while (actionRequests.size() <= index) {
1012 ActionRequestValue actionRequest = new ActionRequestFactory(this).createBlankActionRequest();
1013 actionRequest.setNodeInstance(new RouteNodeInstance());
1014 actionRequests.add(actionRequest);
1015 }
1016 return actionRequests.get(index);
1017 }
1018
1019 public ActionTakenValue getDocActionTaken(int index) {
1020 List<ActionTakenValue> actionsTaken = getActionsTaken();
1021 while (actionsTaken.size() <= index) {
1022 actionsTaken.add(new ActionTakenValue());
1023 }
1024 return actionsTaken.get(index);
1025 }
1026
1027 public ActionItem getDocActionItem(int index) {
1028 List<ActionItem> actionItems = getActionItems();
1029 while (actionItems.size() <= index) {
1030 actionItems.add(new ActionItem());
1031 }
1032 return actionItems.get(index);
1033 }
1034
1035 private RouteNodeInstance getInitialRouteNodeInstance(int index) {
1036 if (initialRouteNodeInstances.size() >= index) {
1037 return initialRouteNodeInstances.get(index);
1038 }
1039 return null;
1040 }
1041
1042 public boolean isRoutingReport() {
1043 return routingReport;
1044 }
1045
1046 public void setRoutingReport(boolean routingReport) {
1047 this.routingReport = routingReport;
1048 }
1049
1050 public List<RouteNodeInstance> getInitialRouteNodeInstances() {
1051 return initialRouteNodeInstances;
1052 }
1053
1054 public void setInitialRouteNodeInstances(List<RouteNodeInstance> initialRouteNodeInstances) {
1055 this.initialRouteNodeInstances = initialRouteNodeInstances;
1056 }
1057
1058 public List<Note> getNotes() {
1059 return notes;
1060 }
1061
1062 public void setNotes(List<Note> notes) {
1063 this.notes = notes;
1064 }
1065
1066 public DocumentRouteHeaderValueContent getDocumentContent() {
1067 if (documentContent == null) {
1068 documentContent = KEWServiceLocator.getRouteHeaderService().getContent(getDocumentId());
1069 }
1070 return documentContent;
1071 }
1072
1073 public void setDocumentContent(DocumentRouteHeaderValueContent documentContent) {
1074 this.documentContent = documentContent;
1075 }
1076
1077 public List<DocumentStatusTransition> getAppDocStatusHistory() {
1078 return this.appDocStatusHistory;
1079 }
1080
1081 public void setAppDocStatusHistory(
1082 List<DocumentStatusTransition> appDocStatusHistory) {
1083 this.appDocStatusHistory = appDocStatusHistory;
1084 }
1085
1086 @Override
1087 public DocumentStatus getStatus() {
1088 return DocumentStatus.fromCode(getDocRouteStatus());
1089 }
1090
1091 @Override
1092 public DateTime getDateCreated() {
1093 if (getCreateDate() == null) {
1094 return null;
1095 }
1096 return new DateTime(getCreateDate().getTime());
1097 }
1098
1099 @Override
1100 public DateTime getDateLastModified() {
1101 if (getDateModified() == null) {
1102 return null;
1103 }
1104 return new DateTime(getDateModified().getTime());
1105 }
1106
1107 @Override
1108 public DateTime getDateApproved() {
1109 if (getApprovedDate() == null) {
1110 return null;
1111 }
1112 return new DateTime(getApprovedDate().getTime());
1113 }
1114
1115 @Override
1116 public DateTime getDateFinalized() {
1117 if (getFinalizedDate() == null) {
1118 return null;
1119 }
1120 return new DateTime(getFinalizedDate().getTime());
1121 }
1122
1123 @Override
1124 public String getTitle() {
1125 return docTitle;
1126 }
1127
1128 @Override
1129 public String getApplicationDocumentId() {
1130 return appDocId;
1131 }
1132
1133 @Override
1134 public String getInitiatorPrincipalId() {
1135 return initiatorWorkflowId;
1136 }
1137
1138 @Override
1139 public String getRoutedByPrincipalId() {
1140 return routedByUserWorkflowId;
1141 }
1142
1143 @Override
1144 public String getDocumentTypeName() {
1145 return getDocumentType().getName();
1146 }
1147
1148 @Override
1149 public String getDocumentHandlerUrl() {
1150 return getDocumentType().getResolvedDocumentHandlerUrl();
1151 }
1152
1153 @Override
1154 public String getApplicationDocumentStatus() {
1155 return appDocStatus;
1156 }
1157
1158 @Override
1159 public DateTime getApplicationDocumentStatusDate() {
1160 if (appDocStatusDate == null) {
1161 return null;
1162 }
1163 return new DateTime(appDocStatusDate.getTime());
1164 }
1165
1166 @Override
1167 public Map<String, String> getVariables() {
1168 Map<String, String> documentVariables = new HashMap<String, String>();
1169
1170
1171 Branch routeNodeInstanceBranch = getRootBranch();
1172
1173
1174 if (routeNodeInstanceBranch != null) {
1175 List<BranchState> listOfBranchStates = routeNodeInstanceBranch.getBranchState();
1176 for (BranchState bs : listOfBranchStates) {
1177 if (bs.getKey() != null && bs.getKey().startsWith(BranchState.VARIABLE_PREFIX)) {
1178 if ( LOG.isDebugEnabled() ) {
1179 if ( LOG.isDebugEnabled() ) {
1180 LOG.debug("Setting branch state variable on vo: " + bs.getKey() + "=" + bs.getValue());
1181 }
1182 }
1183 documentVariables.put(bs.getKey().substring(BranchState.VARIABLE_PREFIX.length()), bs.getValue());
1184 }
1185 }
1186 }
1187 return documentVariables;
1188 }
1189
1190 public static Document to(DocumentRouteHeaderValue documentBo) {
1191 if (documentBo == null) {
1192 return null;
1193 }
1194 Document.Builder builder = Document.Builder.create(documentBo);
1195 return builder.build();
1196 }
1197
1198 public static DocumentRouteHeaderValue from(Document document) {
1199 DocumentRouteHeaderValue documentBo = new DocumentRouteHeaderValue();
1200 documentBo.setAppDocId(document.getApplicationDocumentId());
1201 if (document.getDateApproved() != null) {
1202 documentBo.setApprovedDate(new Timestamp(document.getDateApproved().getMillis()));
1203 }
1204 if (document.getDateCreated() != null) {
1205 documentBo.setCreateDate(new Timestamp(document.getDateCreated().getMillis()));
1206 }
1207 if (StringUtils.isEmpty(documentBo.getDocContent())) {
1208 documentBo.setDocContent(KewApiConstants.DEFAULT_DOCUMENT_CONTENT);
1209 }
1210 documentBo.setDocRouteStatus(document.getStatus().getCode());
1211 documentBo.setDocTitle(document.getTitle());
1212 if (document.getDocumentTypeName() != null) {
1213 DocumentType documentType = KEWServiceLocator.getDocumentTypeService().findByName(document.getDocumentTypeName());
1214 if (documentType == null) {
1215 throw new RiceRuntimeException("Could not locate the given document type name: " + document.getDocumentTypeName());
1216 }
1217 documentBo.setDocumentTypeId(documentType.getDocumentTypeId());
1218 }
1219 if (document.getDateFinalized() != null) {
1220 documentBo.setFinalizedDate(new Timestamp(document.getDateFinalized().getMillis()));
1221 }
1222 documentBo.setInitiatorWorkflowId(document.getInitiatorPrincipalId());
1223 documentBo.setRoutedByUserWorkflowId(document.getRoutedByPrincipalId());
1224 documentBo.setDocumentId(document.getDocumentId());
1225 if (document.getDateLastModified() != null) {
1226 documentBo.setDateModified(new Timestamp(document.getDateLastModified().getMillis()));
1227 }
1228 documentBo.setAppDocStatus(document.getApplicationDocumentStatus());
1229 if (document.getApplicationDocumentStatusDate() != null) {
1230 documentBo.setAppDocStatusDate(new Timestamp(document.getApplicationDocumentStatusDate().getMillis()));
1231 }
1232
1233
1234
1235 Map<String, String> variables = document.getVariables();
1236 if( variables != null && !variables.isEmpty()){
1237 for(Map.Entry<String, String> kvp : variables.entrySet()){
1238 documentBo.setVariable(kvp.getKey(), kvp.getValue());
1239 }
1240 }
1241
1242 return documentBo;
1243 }
1244
1245 @Override
1246 public void refresh() {
1247 }
1248
1249 public DocumentRouteHeaderValue deepCopy(Map<Object, Object> visited) {
1250 if (visited.containsKey(this)) {
1251 return (DocumentRouteHeaderValue)visited.get(this);
1252 }
1253 DocumentRouteHeaderValue copy = new DocumentRouteHeaderValue();
1254 visited.put(this, copy);
1255 copy.documentId = documentId;
1256 copy.documentTypeId = documentTypeId;
1257 copy.docRouteStatus = docRouteStatus;
1258 copy.docRouteLevel = docRouteLevel;
1259 copy.dateModified = copyTimestamp(dateModified);
1260 copy.createDate = copyTimestamp(createDate);
1261 copy.approvedDate = copyTimestamp(approvedDate);
1262 copy.finalizedDate = copyTimestamp(finalizedDate);
1263 copy.docTitle = docTitle;
1264 copy.appDocId = appDocId;
1265 copy.docVersion = docVersion;
1266 copy.initiatorWorkflowId = initiatorWorkflowId;
1267 copy.routedByUserWorkflowId = routedByUserWorkflowId;
1268 copy.routeStatusDate = copyTimestamp(routeStatusDate);
1269 copy.appDocStatus = appDocStatus;
1270 copy.appDocStatusDate = copyTimestamp(appDocStatusDate);
1271 if (documentContent != null) {
1272 copy.documentContent = documentContent.deepCopy(visited);
1273 }
1274 copy.routingReport = routingReport;
1275 if (initialRouteNodeInstances != null) {
1276 List<RouteNodeInstance> copies = new ArrayList<RouteNodeInstance>();
1277 for (RouteNodeInstance routeNodeInstance : initialRouteNodeInstances) {
1278 copies.add(routeNodeInstance.deepCopy(visited));
1279 }
1280 copy.setInitialRouteNodeInstances(copies);
1281 }
1282 if (appDocStatusHistory != null) {
1283 List<DocumentStatusTransition> copies = new ArrayList<DocumentStatusTransition>();
1284 for (DocumentStatusTransition documentStatusTransition : appDocStatusHistory) {
1285 copies.add(documentStatusTransition.deepCopy(visited));
1286 }
1287 copy.setAppDocStatusHistory(copies);
1288 }
1289 if (notes != null) {
1290 List<Note> copies = new ArrayList<Note>();
1291 for (Note note : notes) {
1292 copies.add(note.deepCopy(visited));
1293 }
1294 copy.setNotes(copies);
1295 }
1296
1297 return copy;
1298 }
1299
1300 private Timestamp copyTimestamp(Timestamp timestamp) {
1301 if (timestamp == null) {
1302 return null;
1303 }
1304 return new Timestamp(timestamp.getTime());
1305 }
1306
1307 }