1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.impl.document;
17
18 import java.io.Serializable;
19 import java.util.Arrays;
20 import java.util.Collections;
21 import java.util.Date;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.joda.time.DateTime;
29 import org.kuali.rice.core.api.uif.RemotableAttributeErrorContract;
30 import org.kuali.rice.kew.api.KewApiConstants;
31 import org.kuali.rice.kew.api.KewApiServiceLocator;
32 import org.kuali.rice.kew.api.action.ActionRequest;
33 import org.kuali.rice.kew.api.action.ActionRequestType;
34 import org.kuali.rice.kew.api.action.ActionTaken;
35 import org.kuali.rice.kew.api.action.ActionType;
36 import org.kuali.rice.kew.api.action.AdHocRevoke;
37 import org.kuali.rice.kew.api.action.AdHocToGroup;
38 import org.kuali.rice.kew.api.action.AdHocToPrincipal;
39 import org.kuali.rice.kew.api.action.DocumentActionParameters;
40 import org.kuali.rice.kew.api.action.DocumentActionResult;
41 import org.kuali.rice.kew.api.action.MovePoint;
42 import org.kuali.rice.kew.api.action.RequestedActions;
43 import org.kuali.rice.kew.api.action.ReturnPoint;
44 import org.kuali.rice.kew.api.action.ValidActions;
45 import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
46 import org.kuali.rice.kew.api.document.Document;
47 import org.kuali.rice.kew.api.document.DocumentContent;
48 import org.kuali.rice.kew.api.document.DocumentContentUpdate;
49 import org.kuali.rice.kew.api.document.DocumentDetail;
50 import org.kuali.rice.kew.api.document.DocumentStatus;
51 import org.kuali.rice.kew.api.document.DocumentUpdate;
52 import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
53 import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
54 import org.kuali.rice.kew.api.document.WorkflowDocumentService;
55
56
57
58
59
60
61
62
63 public class WorkflowDocumentImpl implements Serializable, WorkflowDocumentPrototype {
64
65 private static final long serialVersionUID = -3672966990721719088L;
66
67
68
69
70 private String principalId;
71
72
73
74 private ModifiableDocument modifiableDocument;
75
76
77
78 private ModifiableDocumentContent modifiableDocumentContent;
79
80
81
82
83 private ValidActions validActions;
84
85
86
87
88 private RequestedActions requestedActions;
89
90
91
92 private boolean documentDeleted = false;
93
94 private transient WorkflowDocumentActionsService workflowDocumentActionsService;
95 private transient WorkflowDocumentService workflowDocumentService;
96
97 public void init(String principalId, Document document) {
98 if (StringUtils.isBlank("principalId")) {
99 throw new IllegalArgumentException("principalId was null or blank");
100 }
101 if (document == null) {
102 throw new IllegalArgumentException("document was null");
103 }
104 this.principalId = principalId;
105 this.modifiableDocument = new ModifiableDocument(document);
106 this.modifiableDocumentContent = null;
107 this.validActions = null;
108 this.requestedActions = null;
109 }
110
111 public WorkflowDocumentActionsService getWorkflowDocumentActionsService() {
112 if (workflowDocumentActionsService == null) {
113 workflowDocumentActionsService = KewApiServiceLocator.getWorkflowDocumentActionsService();
114 }
115 return workflowDocumentActionsService;
116 }
117
118 public void setWorkflowDocumentActionsService(WorkflowDocumentActionsService workflowDocumentActionsService) {
119 this.workflowDocumentActionsService = workflowDocumentActionsService;
120 }
121
122 public WorkflowDocumentService getWorkflowDocumentService() {
123 if (workflowDocumentService == null) {
124 workflowDocumentService = KewApiServiceLocator.getWorkflowDocumentService();
125 }
126 return workflowDocumentService;
127 }
128
129 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
130 this.workflowDocumentService = workflowDocumentService;
131 }
132
133 protected ModifiableDocument getModifiableDocument() {
134 return modifiableDocument;
135 }
136
137 protected ModifiableDocumentContent getModifiableDocumentContent() {
138 if (this.modifiableDocumentContent == null) {
139 DocumentContent documentContent = getWorkflowDocumentService().getDocumentContent(getDocumentId());
140 if (documentContent == null) {
141 throw new IllegalStateException("Failed to load document content for documentId: " + getDocumentId());
142 }
143 this.modifiableDocumentContent = new ModifiableDocumentContent(documentContent);
144 }
145 return this.modifiableDocumentContent;
146 }
147
148 @Override
149 public String getDocumentId() {
150 if (documentDeleted) {
151 throw new IllegalStateException("Document has been deleted.");
152 }
153 return getModifiableDocument().getDocumentId();
154 }
155
156 @Override
157 public Document getDocument() {
158 return getModifiableDocument().getDocument();
159 }
160
161 @Override
162 public DocumentContent getDocumentContent() {
163 return getModifiableDocumentContent().getDocumentContent();
164 }
165
166 @Override
167 public String getApplicationContent() {
168 return getDocumentContent().getApplicationContent();
169 }
170
171 @Override
172 public void setApplicationContent(String applicationContent) {
173 getModifiableDocumentContent().setApplicationContent(applicationContent);
174 }
175
176 @Override
177 public void setAttributeContent(String attributeContent) {
178 getModifiableDocumentContent().setAttributeContent(attributeContent);
179 }
180
181 @Override
182 public void clearAttributeContent() {
183 getModifiableDocumentContent().setAttributeContent("");
184 }
185
186 @Override
187 public String getAttributeContent() {
188 return getDocumentContent().getAttributeContent();
189 }
190
191 @Override
192 public void addAttributeDefinition(WorkflowAttributeDefinition attributeDefinition) {
193 getModifiableDocumentContent().addAttributeDefinition(attributeDefinition);
194 }
195
196 @Override
197 public void removeAttributeDefinition(WorkflowAttributeDefinition attributeDefinition) {
198 getModifiableDocumentContent().removeAttributeDefinition(attributeDefinition);
199 }
200
201 @Override
202 public void clearAttributeDefinitions() {
203 getAttributeDefinitions().clear();
204 }
205
206 @Override
207 public List<WorkflowAttributeDefinition> getAttributeDefinitions() {
208 return getModifiableDocumentContent().getAttributeDefinitions();
209 }
210
211 @Override
212 public void setSearchableContent(String searchableContent) {
213 getModifiableDocumentContent().setSearchableContent(searchableContent);
214 }
215
216 @Override
217 public void addSearchableDefinition(WorkflowAttributeDefinition searchableDefinition) {
218 getModifiableDocumentContent().addSearchableDefinition(searchableDefinition);
219 }
220
221 @Override
222 public void removeSearchableDefinition(WorkflowAttributeDefinition searchableDefinition) {
223 getModifiableDocumentContent().removeSearchableDefinition(searchableDefinition);
224 }
225
226 @Override
227 public void clearSearchableDefinitions() {
228 getSearchableDefinitions().clear();
229 }
230
231 @Override
232 public void clearSearchableContent() {
233 getModifiableDocumentContent().setSearchableContent("");
234 }
235
236 @Override
237 public List<WorkflowAttributeDefinition> getSearchableDefinitions() {
238 return getModifiableDocumentContent().getSearchableDefinitions();
239 }
240
241 @Override
242 public List<? extends RemotableAttributeErrorContract> validateAttributeDefinition(
243 WorkflowAttributeDefinition attributeDefinition) {
244 return getWorkflowDocumentActionsService().validateWorkflowAttributeDefinition(attributeDefinition);
245 }
246
247 @Override
248 public List<ActionRequest> getRootActionRequests() {
249 return getWorkflowDocumentService().getRootActionRequests(getDocumentId());
250 }
251
252 @Override
253 public List<ActionTaken> getActionsTaken() {
254 return getWorkflowDocumentService().getActionsTaken(getDocumentId());
255 }
256
257 @Override
258 public void setApplicationDocumentId(String applicationDocumentId) {
259 getModifiableDocument().setApplicationDocumentId(applicationDocumentId);
260 }
261
262 @Override
263 public String getApplicationDocumentId() {
264 return getModifiableDocument().getApplicationDocumentId();
265 }
266
267 @Override
268 public DateTime getDateCreated() {
269 return getModifiableDocument().getDateCreated();
270 }
271
272 @Override
273 public String getTitle() {
274 return getModifiableDocument().getTitle();
275 }
276
277 @Override
278 public ValidActions getValidActions() {
279 if (validActions == null) {
280 validActions = getWorkflowDocumentActionsService().determineValidActions(getDocumentId(), getPrincipalId());
281 }
282 return validActions;
283 }
284
285 @Override
286 public RequestedActions getRequestedActions() {
287 if (requestedActions == null) {
288 requestedActions = getWorkflowDocumentActionsService().determineRequestedActions(getDocumentId(),
289 getPrincipalId());
290 }
291 return requestedActions;
292 }
293
294 protected DocumentUpdate getDocumentUpdateIfDirty() {
295 if (getModifiableDocument().isDirty()) {
296 return getModifiableDocument().build();
297 }
298 return null;
299 }
300
301 protected DocumentContentUpdate getDocumentContentUpdateIfDirty() {
302 if (getModifiableDocumentContent().isDirty()) {
303 return getModifiableDocumentContent().build();
304 }
305 return null;
306 }
307
308 protected void resetStateAfterAction(DocumentActionResult response) {
309 this.modifiableDocument = new ModifiableDocument(response.getDocument());
310 this.validActions = null;
311 if (response.getValidActions() != null) {
312 this.validActions = response.getValidActions();
313 }
314 this.requestedActions = null;
315 if (response.getRequestedActions() != null) {
316 this.requestedActions = response.getRequestedActions();
317 }
318
319 this.modifiableDocumentContent = null;
320 }
321
322 @Override
323 public void saveDocument(String annotation) {
324 DocumentActionResult result = getWorkflowDocumentActionsService().save(
325 constructDocumentActionParameters(annotation));
326 resetStateAfterAction(result);
327 }
328
329 @Override
330 public void route(String annotation) {
331 DocumentActionResult result = getWorkflowDocumentActionsService().route(
332 constructDocumentActionParameters(annotation));
333 resetStateAfterAction(result);
334 }
335
336 @Override
337 public void disapprove(String annotation) {
338 DocumentActionResult result = getWorkflowDocumentActionsService().disapprove(
339 constructDocumentActionParameters(annotation));
340 resetStateAfterAction(result);
341 }
342
343 @Override
344 public void approve(String annotation) {
345 DocumentActionResult result = getWorkflowDocumentActionsService().approve(
346 constructDocumentActionParameters(annotation));
347 resetStateAfterAction(result);
348 }
349
350 @Override
351 public void cancel(String annotation) {
352 DocumentActionResult result = getWorkflowDocumentActionsService().cancel(
353 constructDocumentActionParameters(annotation));
354 resetStateAfterAction(result);
355 }
356
357 @Override
358 public void recall(String annotation, boolean cancel) {
359 DocumentActionResult result = getWorkflowDocumentActionsService().recall(
360 constructDocumentActionParameters(annotation), cancel);
361 resetStateAfterAction(result);
362 }
363
364 @Override
365 public void blanketApprove(String annotation) {
366 DocumentActionResult result = getWorkflowDocumentActionsService().blanketApprove(
367 constructDocumentActionParameters(annotation));
368 resetStateAfterAction(result);
369 }
370
371 @Override
372 public void blanketApprove(String annotation, String... nodeNames) {
373 if (nodeNames == null) {
374 throw new IllegalArgumentException("nodeNames was null");
375 }
376 Set<String> nodeNamesSet = new HashSet<String>(Arrays.asList(nodeNames));
377 DocumentActionResult result = getWorkflowDocumentActionsService().blanketApproveToNodes(
378 constructDocumentActionParameters(annotation), nodeNamesSet);
379 resetStateAfterAction(result);
380 }
381
382 @Override
383 public void saveDocumentData() {
384 DocumentActionResult result = getWorkflowDocumentActionsService().saveDocumentData(
385 constructDocumentActionParameters(null));
386 resetStateAfterAction(result);
387 }
388
389 @Override
390 public void setApplicationDocumentStatus(String applicationDocumentStatus) {
391 getModifiableDocument().setApplicationDocumentStatus(applicationDocumentStatus);
392 }
393
394 @Override
395 public void acknowledge(String annotation) {
396 DocumentActionResult result = getWorkflowDocumentActionsService().acknowledge(
397 constructDocumentActionParameters(annotation));
398 resetStateAfterAction(result);
399 }
400
401 @Override
402 public void fyi(String annotation) {
403 DocumentActionResult result = getWorkflowDocumentActionsService().clearFyi(
404 constructDocumentActionParameters(annotation));
405 resetStateAfterAction(result);
406 }
407
408 @Override
409 public void fyi() {
410 fyi("");
411 }
412
413 @Override
414 public void delete() {
415 getWorkflowDocumentActionsService().delete(getDocumentId(), principalId);
416 documentDeleted = true;
417 }
418
419 @Override
420 public void refresh() {
421 Document document = getWorkflowDocumentService().getDocument(getDocumentId());
422 this.modifiableDocument = new ModifiableDocument(document);
423 this.validActions = null;
424 this.requestedActions = null;
425 this.modifiableDocumentContent = null;
426 }
427
428 @Override
429 public void adHocToPrincipal(ActionRequestType actionRequested, String annotation, String targetPrincipalId,
430 String responsibilityDescription, boolean forceAction) {
431 adHocToPrincipal(actionRequested, null, annotation, targetPrincipalId, responsibilityDescription, forceAction);
432 }
433
434 @Override
435 public void adHocToPrincipal(ActionRequestType actionRequested, String nodeName, String annotation,
436 String targetPrincipalId, String responsibilityDescription, boolean forceAction) {
437 adHocToPrincipal(actionRequested, nodeName, annotation, targetPrincipalId, responsibilityDescription,
438 forceAction, null);
439 }
440
441 @Override
442 public void adHocToPrincipal(ActionRequestType actionRequested, String nodeName, String annotation,
443 String targetPrincipalId, String responsibilityDescription, boolean forceAction, String requestLabel) {
444 AdHocToPrincipal.Builder builder = AdHocToPrincipal.Builder
445 .create(actionRequested, nodeName, targetPrincipalId);
446 builder.setResponsibilityDescription(responsibilityDescription);
447 builder.setForceAction(forceAction);
448 builder.setRequestLabel(requestLabel);
449 DocumentActionResult result = getWorkflowDocumentActionsService().adHocToPrincipal(
450 constructDocumentActionParameters(annotation), builder.build());
451 resetStateAfterAction(result);
452 }
453
454 @Override
455 public void adHocToPrincipal(AdHocToPrincipal adHocToPrincipal, String annotation) {
456 DocumentActionResult result = getWorkflowDocumentActionsService().adHocToPrincipal(
457 constructDocumentActionParameters(annotation), adHocToPrincipal);
458 resetStateAfterAction(result);
459 }
460
461 @Override
462 public void adHocToGroup(ActionRequestType actionRequested, String annotation, String targetGroupId,
463 String responsibilityDescription, boolean forceAction) {
464 adHocToGroup(actionRequested, null, annotation, targetGroupId, responsibilityDescription, forceAction);
465 }
466
467 @Override
468 public void adHocToGroup(ActionRequestType actionRequested, String nodeName, String annotation,
469 String targetGroupId, String responsibilityDescription, boolean forceAction) {
470 adHocToGroup(actionRequested, nodeName, annotation, targetGroupId, responsibilityDescription, forceAction, null);
471 }
472
473 @Override
474 public void adHocToGroup(ActionRequestType actionRequested, String nodeName, String annotation,
475 String targetGroupId, String responsibilityDescription, boolean forceAction, String requestLabel) {
476 AdHocToGroup.Builder builder = AdHocToGroup.Builder.create(actionRequested, nodeName, targetGroupId);
477 builder.setResponsibilityDescription(responsibilityDescription);
478 builder.setForceAction(forceAction);
479 builder.setRequestLabel(requestLabel);
480 DocumentActionResult result = getWorkflowDocumentActionsService().adHocToGroup(
481 constructDocumentActionParameters(annotation), builder.build());
482 resetStateAfterAction(result);
483 }
484
485 @Override
486 public void adHocToGroup(AdHocToGroup adHocToGroup, String annotation) {
487 DocumentActionResult result = getWorkflowDocumentActionsService().adHocToGroup(
488 constructDocumentActionParameters(annotation), adHocToGroup);
489 resetStateAfterAction(result);
490 }
491
492 @Override
493 public void revokeAdHocRequestById(String actionRequestId, String annotation) {
494 if (StringUtils.isBlank(actionRequestId)) {
495 throw new IllegalArgumentException("actionRequestId was null or blank");
496 }
497 DocumentActionResult result = getWorkflowDocumentActionsService().revokeAdHocRequestById(
498 constructDocumentActionParameters(annotation), actionRequestId);
499 resetStateAfterAction(result);
500 }
501
502 @Override
503 public void revokeAdHocRequests(AdHocRevoke revoke, String annotation) {
504 if (revoke == null) {
505 throw new IllegalArgumentException("revokeFromPrincipal was null");
506 }
507 DocumentActionResult result = getWorkflowDocumentActionsService().revokeAdHocRequests(
508 constructDocumentActionParameters(annotation), revoke);
509 resetStateAfterAction(result);
510 }
511
512 @Override
513 public void revokeAllAdHocRequests(String annotation) {
514 DocumentActionResult result = getWorkflowDocumentActionsService().revokeAllAdHocRequests(
515 constructDocumentActionParameters(annotation));
516 resetStateAfterAction(result);
517 }
518
519 @Override
520 public void setTitle(String title) {
521 getModifiableDocument().setTitle(title);
522 }
523
524 @Override
525 public String getDocumentTypeName() {
526 return getDocument().getDocumentTypeName();
527 }
528
529 @Override
530 public boolean isCompletionRequested() {
531 return getRequestedActions().isCompleteRequested();
532 }
533
534 @Override
535 public boolean isApprovalRequested() {
536 return getRequestedActions().isApproveRequested();
537 }
538
539 @Override
540 public boolean isAcknowledgeRequested() {
541 return getRequestedActions().isAcknowledgeRequested();
542 }
543
544 @Override
545 public boolean isFYIRequested() {
546 return getRequestedActions().isFyiRequested();
547 }
548
549 @Override
550 public boolean isBlanketApproveCapable() {
551 return isValidAction(ActionType.BLANKET_APPROVE)
552 && (isCompletionRequested() || isApprovalRequested() || isInitiated());
553 }
554
555 @Override
556 public boolean isRouteCapable() {
557 return isValidAction(ActionType.ROUTE);
558 }
559
560 @Override
561 public boolean isValidAction(ActionType actionType) {
562 if (actionType == null) {
563 throw new IllegalArgumentException("actionType was null");
564 }
565 return getValidActions().getValidActions().contains(actionType);
566 }
567
568 @Override
569 public void superUserBlanketApprove(String annotation) {
570 DocumentActionResult result = getWorkflowDocumentActionsService().superUserBlanketApprove(
571 constructDocumentActionParameters(annotation), true);
572 resetStateAfterAction(result);
573 }
574
575 @Override
576 public void superUserNodeApprove(String nodeName, String annotation) {
577 DocumentActionResult result = getWorkflowDocumentActionsService().superUserNodeApprove(
578 constructDocumentActionParameters(annotation), true, nodeName);
579 resetStateAfterAction(result);
580 }
581
582 @Override
583 public void superUserTakeRequestedAction(String actionRequestId, String annotation) {
584 DocumentActionResult result = getWorkflowDocumentActionsService().superUserTakeRequestedAction(
585 constructDocumentActionParameters(annotation), true, actionRequestId);
586 resetStateAfterAction(result);
587 }
588
589 @Override
590 public void superUserDisapprove(String annotation) {
591 DocumentActionResult result = getWorkflowDocumentActionsService().superUserDisapprove(
592 constructDocumentActionParameters(annotation), true);
593 resetStateAfterAction(result);
594 }
595
596 @Override
597 public void superUserCancel(String annotation) {
598 DocumentActionResult result = getWorkflowDocumentActionsService().superUserCancel(
599 constructDocumentActionParameters(annotation), true);
600 resetStateAfterAction(result);
601 }
602
603 @Override
604 public void superUserReturnToPreviousNode(ReturnPoint returnPoint, String annotation) {
605 DocumentActionResult result = getWorkflowDocumentActionsService().superUserReturnToPreviousNode(
606 constructDocumentActionParameters(annotation), true, returnPoint);
607 resetStateAfterAction(result);
608 }
609
610 @Override
611 public void complete(String annotation) {
612 DocumentActionResult result = getWorkflowDocumentActionsService().complete(
613 constructDocumentActionParameters(annotation));
614 resetStateAfterAction(result);
615 }
616
617 @Override
618 public void logAnnotation(String annotation) {
619 getWorkflowDocumentActionsService().logAnnotation(getDocumentId(), principalId, annotation);
620 }
621
622 @Override
623 public DocumentStatus getStatus() {
624 return getDocument().getStatus();
625 }
626
627 @Override
628 public boolean checkStatus(DocumentStatus status) {
629 if (status == null) {
630 throw new IllegalArgumentException("status was null");
631 }
632 return status == getStatus();
633 }
634
635
636
637
638
639
640 @Override
641 public boolean isInitiated() {
642 return checkStatus(DocumentStatus.INITIATED);
643 }
644
645
646
647
648
649
650 @Override
651 public boolean isSaved() {
652 return checkStatus(DocumentStatus.SAVED);
653 }
654
655
656
657
658
659
660 @Override
661 public boolean isEnroute() {
662 return checkStatus(DocumentStatus.ENROUTE);
663 }
664
665
666
667
668
669
670 @Override
671 public boolean isException() {
672 return checkStatus(DocumentStatus.EXCEPTION);
673 }
674
675
676
677
678
679
680 @Override
681 public boolean isCanceled() {
682 return checkStatus(DocumentStatus.CANCELED);
683 }
684
685
686
687
688
689
690 @Override
691 public boolean isRecalled() {
692 return checkStatus(DocumentStatus.RECALLED);
693 }
694
695
696
697
698
699
700 @Override
701 public boolean isDisapproved() {
702 return checkStatus(DocumentStatus.DISAPPROVED);
703 }
704
705
706
707
708
709
710 @Override
711 public boolean isApproved() {
712 return isProcessed() || isFinal();
713 }
714
715
716
717
718
719
720 @Override
721 public boolean isProcessed() {
722 return checkStatus(DocumentStatus.PROCESSED);
723 }
724
725
726
727
728
729
730 @Override
731 public boolean isFinal() {
732 return checkStatus(DocumentStatus.FINAL);
733 }
734
735
736
737
738
739
740 @Override
741 public String getPrincipalId() {
742 return principalId;
743 }
744
745 @Override
746 public void switchPrincipal(String principalId) {
747 if (StringUtils.isBlank(this.principalId)) {
748 throw new IllegalArgumentException("principalId was null or blank");
749 }
750 this.principalId = principalId;
751 this.validActions = null;
752 this.requestedActions = null;
753 }
754
755 @Override
756 public void takeGroupAuthority(String annotation, String groupId) {
757 DocumentActionResult result = getWorkflowDocumentActionsService().takeGroupAuthority(
758 constructDocumentActionParameters(annotation), groupId);
759 resetStateAfterAction(result);
760 }
761
762 @Override
763 public void releaseGroupAuthority(String annotation, String groupId) {
764 DocumentActionResult result = getWorkflowDocumentActionsService().releaseGroupAuthority(
765 constructDocumentActionParameters(annotation), groupId);
766 resetStateAfterAction(result);
767 }
768
769 @Override
770 public Set<String> getNodeNames() {
771 final List<String> names = getWorkflowDocumentService().getActiveRouteNodeNames(getDocumentId());
772 return Collections.unmodifiableSet(new HashSet<String>(names));
773 }
774
775 public Set<String> getCurrentNodeNames() {
776 final List<String> names = getWorkflowDocumentService().getCurrentRouteNodeNames(getDocumentId());
777 return Collections.unmodifiableSet(new HashSet<String>(names));
778 }
779
780 @Override
781 public void returnToPreviousNode(String annotation, String nodeName) {
782 if (nodeName == null) {
783 throw new IllegalArgumentException("nodeName was null");
784 }
785 returnToPreviousNode(annotation, ReturnPoint.create(nodeName));
786 }
787
788 @Override
789 public void returnToPreviousNode(String annotation, ReturnPoint returnPoint) {
790 if (returnPoint == null) {
791 throw new IllegalArgumentException("returnPoint was null");
792 }
793 DocumentActionResult result = getWorkflowDocumentActionsService().returnToPreviousNode(
794 constructDocumentActionParameters(annotation), returnPoint);
795 resetStateAfterAction(result);
796 }
797
798 @Override
799 public void move(MovePoint movePoint, String annotation) {
800 if (movePoint == null) {
801 throw new IllegalArgumentException("movePoint was null");
802 }
803 DocumentActionResult result = getWorkflowDocumentActionsService().move(
804 constructDocumentActionParameters(annotation), movePoint);
805 resetStateAfterAction(result);
806 }
807
808 @Override
809 public List<RouteNodeInstance> getActiveRouteNodeInstances() {
810 return getWorkflowDocumentService().getActiveRouteNodeInstances(getDocumentId());
811 }
812
813 @Override
814 public List<RouteNodeInstance> getCurrentRouteNodeInstances() {
815 return getWorkflowDocumentService().getCurrentRouteNodeInstances(getDocumentId());
816 }
817
818 @Override
819 public List<RouteNodeInstance> getRouteNodeInstances() {
820 return getWorkflowDocumentService().getRouteNodeInstances(getDocumentId());
821 }
822
823 @Override
824 public List<String> getPreviousNodeNames() {
825 return getWorkflowDocumentService().getPreviousRouteNodeNames(getDocumentId());
826 }
827
828 @Override
829 public DocumentDetail getDocumentDetail() {
830 return getWorkflowDocumentService().getDocumentDetail(getDocumentId());
831 }
832
833 @Override
834 public void updateDocumentContent(DocumentContentUpdate documentContentUpdate) {
835 if (documentContentUpdate == null) {
836 throw new IllegalArgumentException("documentContentUpdate was null.");
837 }
838 getModifiableDocumentContent().setDocumentContentUpdate(documentContentUpdate);
839 }
840
841 @Override
842 public void placeInExceptionRouting(String annotation) {
843 DocumentActionResult result = getWorkflowDocumentActionsService().placeInExceptionRouting(
844 constructDocumentActionParameters(annotation));
845 resetStateAfterAction(result);
846 }
847
848 @Override
849 public void setVariable(String name, String value) {
850 getModifiableDocument().setVariable(name, value);
851 }
852
853 @Override
854 public String getVariableValue(String name) {
855 return getModifiableDocument().getVariableValue(name);
856 }
857
858 @Override
859 public void setReceiveFutureRequests() {
860 setVariable(getFutureRequestsKey(principalId), getReceiveFutureRequestsValue());
861 }
862
863 @Override
864 public void setDoNotReceiveFutureRequests() {
865 this.setVariable(getFutureRequestsKey(principalId), getDoNotReceiveFutureRequestsValue());
866 }
867
868 @Override
869 public void setClearFutureRequests() {
870 this.setVariable(getFutureRequestsKey(principalId), getClearFutureRequestsValue());
871 }
872
873 protected String getFutureRequestsKey(String principalId) {
874 return KewApiConstants.RECEIVE_FUTURE_REQUESTS_BRANCH_STATE_KEY + "," + principalId + ","
875 + new Date().toString() + ", " + Math.random();
876 }
877
878 @Override
879 public String getReceiveFutureRequestsValue() {
880 return KewApiConstants.RECEIVE_FUTURE_REQUESTS_BRANCH_STATE_VALUE;
881 }
882
883 @Override
884 public String getDoNotReceiveFutureRequestsValue() {
885 return KewApiConstants.DONT_RECEIVE_FUTURE_REQUESTS_BRANCH_STATE_VALUE;
886 }
887
888 @Override
889 public String getClearFutureRequestsValue() {
890 return KewApiConstants.CLEAR_FUTURE_REQUESTS_BRANCH_STATE_VALUE;
891 }
892
893 protected DocumentActionParameters constructDocumentActionParameters(String annotation) {
894 DocumentActionParameters.Builder builder = DocumentActionParameters.Builder.create(getDocumentId(),
895 getPrincipalId());
896 builder.setAnnotation(annotation);
897 builder.setDocumentUpdate(getDocumentUpdateIfDirty());
898 builder.setDocumentContentUpdate(getDocumentContentUpdateIfDirty());
899 return builder.build();
900 }
901
902 @Override
903 public DateTime getDateLastModified() {
904 return getDocument().getDateLastModified();
905 }
906
907 @Override
908 public DateTime getDateApproved() {
909 return getDocument().getDateApproved();
910 }
911
912 @Override
913 public DateTime getDateFinalized() {
914 return getDocument().getDateFinalized();
915 }
916
917 @Override
918 public String getInitiatorPrincipalId() {
919 return getDocument().getInitiatorPrincipalId();
920 }
921
922 @Override
923 public String getRoutedByPrincipalId() {
924 return getDocument().getRoutedByPrincipalId();
925 }
926
927 @Override
928 public String getDocumentTypeId() {
929 return getDocument().getDocumentTypeId();
930 }
931
932 @Override
933 public String getDocumentHandlerUrl() {
934 return getDocument().getDocumentHandlerUrl();
935 }
936
937 @Override
938 public String getApplicationDocumentStatus() {
939 return getDocument().getApplicationDocumentStatus();
940 }
941
942 @Override
943 public DateTime getApplicationDocumentStatusDate() {
944 return getDocument().getApplicationDocumentStatusDate();
945 }
946
947 @Override
948 public Map<String, String> getVariables() {
949 return getDocument().getVariables();
950 }
951
952
953
954
955
956 protected static class ModifiableDocumentContent implements Serializable {
957
958 private static final long serialVersionUID = -4458431160327214042L;
959
960 private boolean dirty;
961 private DocumentContent originalDocumentContent;
962 private DocumentContentUpdate.Builder builder;
963
964 protected ModifiableDocumentContent(DocumentContent documentContent) {
965 this.dirty = false;
966 this.originalDocumentContent = documentContent;
967 this.builder = DocumentContentUpdate.Builder.create(documentContent);
968 }
969
970 protected DocumentContent getDocumentContent() {
971 if (!dirty) {
972 return originalDocumentContent;
973 }
974 DocumentContent.Builder documentContentBuilder = DocumentContent.Builder.create(originalDocumentContent);
975 documentContentBuilder.setApplicationContent(builder.getApplicationContent());
976 documentContentBuilder.setAttributeContent(builder.getAttributeContent());
977 documentContentBuilder.setSearchableContent(builder.getSearchableContent());
978 return documentContentBuilder.build();
979 }
980
981 protected DocumentContentUpdate build() {
982 return builder.build();
983 }
984
985 protected void setDocumentContentUpdate(DocumentContentUpdate update) {
986 this.builder = DocumentContentUpdate.Builder.create(update);
987 this.dirty = true;
988 }
989
990 protected void addAttributeDefinition(WorkflowAttributeDefinition definition) {
991 builder.getAttributeDefinitions().add(definition);
992 dirty = true;
993 }
994
995 protected void removeAttributeDefinition(WorkflowAttributeDefinition definition) {
996 builder.getAttributeDefinitions().remove(definition);
997 dirty = true;
998 }
999
1000 protected List<WorkflowAttributeDefinition> getAttributeDefinitions() {
1001 return builder.getAttributeDefinitions();
1002 }
1003
1004 protected void addSearchableDefinition(WorkflowAttributeDefinition definition) {
1005 builder.getSearchableDefinitions().add(definition);
1006 dirty = true;
1007 }
1008
1009 protected void removeSearchableDefinition(WorkflowAttributeDefinition definition) {
1010 builder.getSearchableDefinitions().remove(definition);
1011 dirty = true;
1012 }
1013
1014 protected List<WorkflowAttributeDefinition> getSearchableDefinitions() {
1015 return builder.getAttributeDefinitions();
1016 }
1017
1018 protected void setApplicationContent(String applicationContent) {
1019 builder.setApplicationContent(applicationContent);
1020 dirty = true;
1021 }
1022
1023 protected void setAttributeContent(String attributeContent) {
1024 builder.setAttributeContent(attributeContent);
1025 dirty = true;
1026 }
1027
1028 public void setAttributeDefinitions(List<WorkflowAttributeDefinition> attributeDefinitions) {
1029 builder.setAttributeDefinitions(attributeDefinitions);
1030 dirty = true;
1031 }
1032
1033 public void setSearchableContent(String searchableContent) {
1034 builder.setSearchableContent(searchableContent);
1035 dirty = true;
1036 }
1037
1038 public void setSearchableDefinitions(List<WorkflowAttributeDefinition> searchableDefinitions) {
1039 builder.setSearchableDefinitions(searchableDefinitions);
1040 dirty = true;
1041 }
1042
1043 boolean isDirty() {
1044 return dirty;
1045 }
1046
1047 }
1048
1049
1050
1051
1052
1053 protected static class ModifiableDocument implements Serializable {
1054
1055 private static final long serialVersionUID = -3234793238863410378L;
1056
1057 private boolean dirty;
1058 private Document originalDocument;
1059 private DocumentUpdate.Builder builder;
1060
1061 protected ModifiableDocument(Document document) {
1062 this.dirty = false;
1063 this.originalDocument = document;
1064 this.builder = DocumentUpdate.Builder.create(document);
1065 }
1066
1067 protected Document getDocument() {
1068 if (!dirty) {
1069 return originalDocument;
1070 }
1071 Document.Builder documentBuilder = Document.Builder.create(originalDocument);
1072 documentBuilder.setApplicationDocumentId(builder.getApplicationDocumentId());
1073 documentBuilder.setTitle(builder.getTitle());
1074 documentBuilder.setApplicationDocumentStatus(builder.getApplicationDocumentStatus());
1075 documentBuilder.setVariables(builder.getVariables());
1076 return documentBuilder.build();
1077 }
1078
1079 protected DocumentUpdate build() {
1080 return builder.build();
1081 }
1082
1083
1084
1085
1086 protected String getDocumentId() {
1087 return originalDocument.getDocumentId();
1088 }
1089
1090
1091
1092
1093 protected DateTime getDateCreated() {
1094 return originalDocument.getDateCreated();
1095 }
1096
1097 protected String getApplicationDocumentId() {
1098 return builder.getApplicationDocumentId();
1099 }
1100
1101 protected void setApplicationDocumentId(String applicationDocumentId) {
1102 builder.setApplicationDocumentId(applicationDocumentId);
1103 dirty = true;
1104 addDirtyField("applicationDocumentId");
1105 }
1106
1107 protected String getTitle() {
1108 return builder.getTitle();
1109 }
1110
1111 protected void setTitle(String title) {
1112 builder.setTitle(title);
1113 dirty = true;
1114 addDirtyField("title");
1115
1116 }
1117
1118 protected String getApplicationDocumentStatus() {
1119 return builder.getApplicationDocumentStatus();
1120 }
1121
1122 protected void setApplicationDocumentStatus(String applicationDocumentStatus) {
1123 builder.setApplicationDocumentStatus(applicationDocumentStatus);
1124 dirty = true;
1125 addDirtyField("applicationDocumentStatus");
1126 }
1127
1128 protected void setVariable(String name, String value) {
1129 builder.setVariable(name, value);
1130 dirty = true;
1131 addDirtyField("var[" + name + "]");
1132 }
1133
1134 protected String getVariableValue(String name) {
1135 return builder.getVariableValue(name);
1136 }
1137
1138 boolean isDirty() {
1139 return dirty;
1140 }
1141
1142 void addDirtyField(String field) {
1143 builder.addDirtyField(field);
1144 }
1145
1146 }
1147
1148 }