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