1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.impl.peopleflow;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.kuali.rice.core.api.config.ConfigurationException;
21 import org.kuali.rice.core.api.membership.MemberType;
22 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
23 import org.kuali.rice.kew.actionrequest.ActionRequestFactory;
24 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
25 import org.kuali.rice.kew.actionrequest.KimGroupRecipient;
26 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
27 import org.kuali.rice.kew.actionrequest.Recipient;
28 import org.kuali.rice.kew.api.action.ActionRequestType;
29 import org.kuali.rice.kew.api.document.Document;
30 import org.kuali.rice.kew.api.document.DocumentContent;
31 import org.kuali.rice.kew.api.peopleflow.PeopleFlowDefinition;
32 import org.kuali.rice.kew.api.peopleflow.PeopleFlowDelegate;
33 import org.kuali.rice.kew.api.peopleflow.PeopleFlowMember;
34 import org.kuali.rice.kew.api.repository.type.KewTypeDefinition;
35 import org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService;
36 import org.kuali.rice.kew.engine.RouteContext;
37 import org.kuali.rice.kew.framework.peopleflow.PeopleFlowTypeService;
38 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
39 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent;
40 import org.kuali.rice.kim.api.role.Role;
41 import org.kuali.rice.kim.api.role.RoleMembership;
42 import org.kuali.rice.kim.api.role.RoleService;
43
44 import javax.xml.namespace.QName;
45 import java.util.Collections;
46 import java.util.List;
47 import java.util.Map;
48
49
50
51
52
53
54
55 public class PeopleFlowRequestGeneratorImpl implements PeopleFlowRequestGenerator {
56
57 private KewTypeRepositoryService typeRepositoryService;
58 private RoleService roleService;
59
60 @Override
61 public List<ActionRequestValue> generateRequests(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) {
62 Context context = new Context(routeContext, peopleFlow, actionRequested);
63 for (PeopleFlowMember member : peopleFlow.getMembers()) {
64 generateRequestForMember(context, member);
65 }
66 return context.getActionRequestFactory().getRequestGraphs();
67 }
68
69 protected void generateRequestForMember(Context context, PeopleFlowMember member) {
70 String actionRequestPolicyCode = null;
71 if (member.getActionRequestPolicy() != null) {
72 actionRequestPolicyCode = member.getActionRequestPolicy().getCode();
73 }
74 if (MemberType.ROLE == member.getMemberType()) {
75 generateRequestForRoleMember(context, member, actionRequestPolicyCode);
76 } else {
77 ActionRequestValue actionRequest = context.getActionRequestFactory().addRootActionRequest(
78 context.getActionRequested().getCode(), member.getPriority(), toRecipient(member), "",
79 member.getResponsibilityId(), Boolean.TRUE, actionRequestPolicyCode, null);
80 if (CollectionUtils.isNotEmpty(member.getDelegates())) {
81 for (PeopleFlowDelegate delegate : member.getDelegates()) {
82 context.getActionRequestFactory().addDelegationRequest(actionRequest, toRecipient(delegate),
83 delegate.getResponsibilityId(), Boolean.TRUE, delegate.getDelegationType(), "", null);
84 }
85 }
86 }
87 }
88
89 protected void generateRequestForRoleMember(Context context, PeopleFlowMember member, String actionRequestPolicyCode) {
90 Map<String, String> roleQualifiers = loadRoleQualifiers(context, member);
91 Role role = getRoleService().getRole(member.getMemberId());
92 if (role == null) {
93 throw new IllegalStateException("Failed to locate a role with the given role id of '" + member.getMemberId() + "'");
94 }
95 List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList(
96 member.getMemberId()), roleQualifiers);
97 if (!CollectionUtils.isEmpty(memberships)) {
98 context.getActionRequestFactory().addKimRoleRequest(context.getActionRequested().getCode(), member.getPriority(),
99 role, memberships, null, member.getResponsibilityId(), true, actionRequestPolicyCode, null);
100 }
101
102 }
103
104 protected Map<String, String> loadRoleQualifiers(Context context, PeopleFlowMember member) {
105 PeopleFlowTypeService peopleFlowTypeService = context.getPeopleFlowTypeService();
106 if (peopleFlowTypeService != null) {
107 Document document = DocumentRouteHeaderValue.to(context.getRouteContext().getDocument());
108 DocumentRouteHeaderValueContent content = new DocumentRouteHeaderValueContent(document.getDocumentId());
109 content.setDocumentContent(context.getRouteContext().getDocumentContent().getDocContent());
110 DocumentContent documentContent = DocumentRouteHeaderValueContent.to(content);
111 Map<String, String> roleQualifiers = peopleFlowTypeService.resolveRoleQualifiers(
112 context.getPeopleFlow().getTypeId(), member.getMemberId(), document, documentContent);
113 if (roleQualifiers != null) {
114 return roleQualifiers;
115 }
116 }
117 return Collections.emptyMap();
118 }
119
120 private Recipient toRecipient(PeopleFlowMember member) {
121 Recipient recipient;
122 if (MemberType.PRINCIPAL == member.getMemberType()) {
123 recipient = new KimPrincipalRecipient(member.getMemberId());
124 } else if (MemberType.GROUP == member.getMemberType()) {
125 recipient = new KimGroupRecipient(member.getMemberId());
126 } else {
127 throw new IllegalStateException("encountered a member type which I did not understand: " +
128 member.getMemberType());
129 }
130 return recipient;
131 }
132
133 private Recipient toRecipient(PeopleFlowDelegate delegate) {
134 Recipient recipient;
135 if (MemberType.PRINCIPAL == delegate.getMemberType()) {
136 recipient = new KimPrincipalRecipient(delegate.getMemberId());
137 } else if (MemberType.GROUP == delegate.getMemberType()) {
138 recipient = new KimGroupRecipient(delegate.getMemberId());
139 } else {
140 throw new IllegalStateException("encountered a delegate member type which I did not understand: " +
141 delegate.getMemberType());
142 }
143 return recipient;
144 }
145
146 public KewTypeRepositoryService getTypeRepositoryService() {
147 return typeRepositoryService;
148 }
149
150 public void setTypeRepositoryService(KewTypeRepositoryService typeRepositoryService) {
151 this.typeRepositoryService = typeRepositoryService;
152 }
153
154 public RoleService getRoleService() {
155 return roleService;
156 }
157
158 public void setRoleService(RoleService roleService) {
159 this.roleService = roleService;
160 }
161
162
163
164
165
166 final class Context {
167
168 private final RouteContext routeContext;
169 private final PeopleFlowDefinition peopleFlow;
170 private final ActionRequestType actionRequested;
171 private final ActionRequestFactory actionRequestFactory;
172
173
174 private PeopleFlowTypeService peopleFlowTypeService;
175 private boolean peopleFlowTypeServiceLoaded = false;
176
177 Context(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) {
178 if (routeContext == null) {
179 throw new IllegalArgumentException("routeContext was null");
180 }
181 if (peopleFlow == null) {
182 throw new IllegalArgumentException("peopleFlow was null");
183 }
184 if (!peopleFlow.isActive()) {
185 throw new ConfigurationException("Attempted to route to a PeopleFlow that is not active! " + peopleFlow);
186 }
187 if (actionRequested == null) {
188 actionRequested = ActionRequestType.APPROVE;
189 }
190 this.routeContext = routeContext;
191 this.peopleFlow = peopleFlow;
192 this.actionRequested = actionRequested;
193 this.actionRequestFactory = new ActionRequestFactory(routeContext);
194 }
195
196 RouteContext getRouteContext() {
197 return routeContext;
198 }
199
200 PeopleFlowDefinition getPeopleFlow() {
201 return peopleFlow;
202 }
203
204 ActionRequestType getActionRequested() {
205 return actionRequested;
206 }
207
208 ActionRequestFactory getActionRequestFactory() {
209 return actionRequestFactory;
210 }
211
212
213
214
215 PeopleFlowTypeService getPeopleFlowTypeService() {
216 if (peopleFlowTypeServiceLoaded) {
217 return this.peopleFlowTypeService;
218 }
219 if (getPeopleFlow().getTypeId() != null) {
220 KewTypeDefinition typeDefinition = getTypeRepositoryService().getTypeById(getPeopleFlow().getTypeId());
221 if (typeDefinition == null) {
222 throw new IllegalStateException("Failed to locate a PeopleFlow type for the given type id of '" + getPeopleFlow().getTypeId() + "'");
223 }
224 if (StringUtils.isNotBlank(typeDefinition.getServiceName())) {
225 this.peopleFlowTypeService = GlobalResourceLoader.getService(QName.valueOf(typeDefinition.getServiceName()));
226 if (this.peopleFlowTypeService == null) {
227 throw new IllegalStateException("Failed to load the PeopleFlowTypeService with the name '" + typeDefinition.getServiceName() + "'");
228 }
229 }
230 }
231 peopleFlowTypeServiceLoaded = true;
232 return this.peopleFlowTypeService;
233 }
234
235 }
236 }