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.CoreConstants;
21 import org.kuali.rice.core.api.config.ConfigurationException;
22 import org.kuali.rice.core.api.membership.MemberType;
23 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
24 import org.kuali.rice.core.api.util.VersionHelper;
25 import org.kuali.rice.kew.actionrequest.ActionRequestFactory;
26 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
27 import org.kuali.rice.kew.actionrequest.KimGroupRecipient;
28 import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient;
29 import org.kuali.rice.kew.actionrequest.Recipient;
30 import org.kuali.rice.kew.api.KewApiConstants;
31 import org.kuali.rice.kew.api.action.ActionRequestType;
32 import org.kuali.rice.kew.api.document.Document;
33 import org.kuali.rice.kew.api.document.DocumentContent;
34 import org.kuali.rice.kew.api.peopleflow.PeopleFlowDefinition;
35 import org.kuali.rice.kew.api.peopleflow.PeopleFlowDelegate;
36 import org.kuali.rice.kew.api.peopleflow.PeopleFlowMember;
37 import org.kuali.rice.kew.api.repository.type.KewTypeDefinition;
38 import org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService;
39 import org.kuali.rice.kew.engine.RouteContext;
40 import org.kuali.rice.kew.framework.peopleflow.PeopleFlowTypeService;
41 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
42 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent;
43 import org.kuali.rice.kim.api.role.Role;
44 import org.kuali.rice.kim.api.role.RoleMembership;
45 import org.kuali.rice.kim.api.role.RoleService;
46 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
47 import org.kuali.rice.ksb.api.bus.Endpoint;
48
49 import javax.xml.namespace.QName;
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.List;
53 import java.util.Map;
54
55
56
57
58
59
60
61 public class PeopleFlowRequestGeneratorImpl implements PeopleFlowRequestGenerator {
62
63 private KewTypeRepositoryService typeRepositoryService;
64 private RoleService roleService;
65
66 @Override
67 public List<ActionRequestValue> generateRequests(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) {
68 Context context = new Context(routeContext, peopleFlow, actionRequested);
69 for (PeopleFlowMember member : peopleFlow.getMembers()) {
70 generateRequestForMember(context, member);
71 }
72 return context.getActionRequestFactory().getRequestGraphs();
73 }
74
75 protected void generateRequestForMember(Context context, PeopleFlowMember member) {
76 String actionRequestPolicyCode = null;
77 if (member.getActionRequestPolicy() != null) {
78 actionRequestPolicyCode = member.getActionRequestPolicy().getCode();
79 }
80 if (MemberType.ROLE == member.getMemberType()) {
81 generateRequestForRoleMember(context, member, actionRequestPolicyCode);
82 } else {
83 ActionRequestValue actionRequest = context.getActionRequestFactory().addRootActionRequest(
84 context.getActionRequested().getCode(), member.getPriority(), toRecipient(member), "",
85 member.getResponsibilityId(), Boolean.TRUE, actionRequestPolicyCode, null);
86 if (CollectionUtils.isNotEmpty(member.getDelegates())) {
87 for (PeopleFlowDelegate delegate : member.getDelegates()) {
88 context.getActionRequestFactory().addDelegationRequest(actionRequest, toRecipient(delegate),
89 delegate.getResponsibilityId(), Boolean.TRUE, delegate.getDelegationType(), "", null);
90 }
91 }
92 }
93 }
94
95 protected void generateRequestForRoleMember(Context context, PeopleFlowMember member, String actionRequestPolicyCode) {
96 List<Map<String, String>> roleQualifierList = loadRoleQualifiers(context, member);
97 Role role = getRoleService().getRole(member.getMemberId());
98
99 if (role == null) {
100 throw new IllegalStateException("Failed to locate a role with the given role id of '" + member.getMemberId() + "'");
101 }
102
103 if (CollectionUtils.isEmpty(roleQualifierList)) {
104 addKimRoleRequest(context, role, member, Collections.<String, String>emptyMap(), actionRequestPolicyCode );
105 } else {
106 for (Map<String, String> roleQualifiers : roleQualifierList) {
107 addKimRoleRequest(context, role, member, roleQualifiers, actionRequestPolicyCode );
108 }
109 }
110
111 }
112
113
114 private void addKimRoleRequest(Context context, Role role, PeopleFlowMember member, Map<String, String> roleQualifiers, String actionRequestPolicyCode) {
115 List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList(
116 member.getMemberId()), roleQualifiers);
117
118 if (!CollectionUtils.isEmpty(memberships)) {
119 context.getActionRequestFactory().addKimRoleRequest(context.getActionRequested().getCode(), member.getPriority(),
120 role, memberships, null, member.getResponsibilityId(), true, actionRequestPolicyCode, null);
121 }
122 }
123
124 protected List<Map<String, String>> loadRoleQualifiers(Context context, PeopleFlowMember member) {
125 PeopleFlowTypeService peopleFlowTypeService = context.getPeopleFlowTypeService();
126 List<Map<String, String>> roleQualifierList = new ArrayList<Map<String, String>>();
127
128 if (peopleFlowTypeService != null) {
129 Document document = DocumentRouteHeaderValue.to(context.getRouteContext().getDocument());
130 DocumentRouteHeaderValueContent content = new DocumentRouteHeaderValueContent(document.getDocumentId());
131 content.setDocumentContent(context.getRouteContext().getDocumentContent().getDocContent());
132 DocumentContent documentContent = DocumentRouteHeaderValueContent.to(content);
133 Map<String, String> roleQualifiers = peopleFlowTypeService.resolveRoleQualifiers(
134 context.getPeopleFlow().getTypeId(), member.getMemberId(), document, documentContent);
135
136 if (roleQualifiers != null) {
137 roleQualifierList.add(roleQualifiers);
138 }
139
140 boolean versionOk = VersionHelper.compareVersion(context.getPeopleFlowTypeServiceVersion(), CoreConstants.Versions.VERSION_2_3_0)!=-1? true:false;
141 if(versionOk) {
142 List<Map<String, String>> multipleRoleQualifiers = peopleFlowTypeService.resolveMultipleRoleQualifiers(
143 context.getPeopleFlow().getTypeId(), member.getMemberId(), document, documentContent);
144
145 if (multipleRoleQualifiers != null) {
146 roleQualifierList.addAll(multipleRoleQualifiers);
147 }
148 }
149
150 }
151
152 return roleQualifierList;
153 }
154
155 private Recipient toRecipient(PeopleFlowMember member) {
156 Recipient recipient;
157 if (MemberType.PRINCIPAL == member.getMemberType()) {
158 recipient = new KimPrincipalRecipient(member.getMemberId());
159 } else if (MemberType.GROUP == member.getMemberType()) {
160 recipient = new KimGroupRecipient(member.getMemberId());
161 } else {
162 throw new IllegalStateException("encountered a member type which I did not understand: " +
163 member.getMemberType());
164 }
165 return recipient;
166 }
167
168 private Recipient toRecipient(PeopleFlowDelegate delegate) {
169 Recipient recipient;
170 if (MemberType.PRINCIPAL == delegate.getMemberType()) {
171 recipient = new KimPrincipalRecipient(delegate.getMemberId());
172 } else if (MemberType.GROUP == delegate.getMemberType()) {
173 recipient = new KimGroupRecipient(delegate.getMemberId());
174 } else {
175 throw new IllegalStateException("encountered a delegate member type which I did not understand: " +
176 delegate.getMemberType());
177 }
178 return recipient;
179 }
180
181 public KewTypeRepositoryService getTypeRepositoryService() {
182 return typeRepositoryService;
183 }
184
185 public void setTypeRepositoryService(KewTypeRepositoryService typeRepositoryService) {
186 this.typeRepositoryService = typeRepositoryService;
187 }
188
189 public RoleService getRoleService() {
190 return roleService;
191 }
192
193 public void setRoleService(RoleService roleService) {
194 this.roleService = roleService;
195 }
196
197
198
199
200
201 final class Context {
202
203 private final RouteContext routeContext;
204 private final PeopleFlowDefinition peopleFlow;
205 private final ActionRequestType actionRequested;
206 private final ActionRequestFactory actionRequestFactory;
207
208
209 private PeopleFlowTypeService peopleFlowTypeService;
210 private boolean peopleFlowTypeServiceLoaded = false;
211 private String peopleFlowTypeServiceVersion;
212
213 Context(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) {
214 if (routeContext == null) {
215 throw new IllegalArgumentException("routeContext was null");
216 }
217 if (peopleFlow == null) {
218 throw new IllegalArgumentException("peopleFlow was null");
219 }
220 if (!peopleFlow.isActive()) {
221 throw new ConfigurationException("Attempted to route to a PeopleFlow that is not active! " + peopleFlow);
222 }
223 if (actionRequested == null) {
224 actionRequested = ActionRequestType.APPROVE;
225 }
226 this.routeContext = routeContext;
227 this.peopleFlow = peopleFlow;
228 this.actionRequested = actionRequested;
229 this.actionRequestFactory = new ActionRequestFactory(routeContext);
230 }
231
232 RouteContext getRouteContext() {
233 return routeContext;
234 }
235
236 PeopleFlowDefinition getPeopleFlow() {
237 return peopleFlow;
238 }
239
240 ActionRequestType getActionRequested() {
241 return actionRequested;
242 }
243
244 ActionRequestFactory getActionRequestFactory() {
245 return actionRequestFactory;
246 }
247
248
249
250
251 PeopleFlowTypeService getPeopleFlowTypeService() {
252 if (peopleFlowTypeServiceLoaded) {
253 return this.peopleFlowTypeService;
254 }
255
256 if (getPeopleFlow().getTypeId() != null) {
257 KewTypeDefinition typeDefinition = getTypeRepositoryService().getTypeById(getPeopleFlow().getTypeId());
258
259 if (typeDefinition == null) {
260 throw new IllegalStateException("Failed to locate a PeopleFlow type for the given type id of '" + getPeopleFlow().getTypeId() + "'");
261 }
262
263 if (StringUtils.isNotBlank(typeDefinition.getServiceName())) {
264 Endpoint endpoint = KsbApiServiceLocator.getServiceBus().getEndpoint(QName.valueOf(typeDefinition.getServiceName()));
265
266 if (endpoint == null) {
267 throw new IllegalStateException("Failed to load the PeopleFlowTypeService with the name '" + typeDefinition.getServiceName() + "'");
268 }
269
270 this.peopleFlowTypeService = (PeopleFlowTypeService)endpoint.getService();
271 this.peopleFlowTypeServiceVersion = endpoint.getServiceConfiguration().getServiceVersion();
272 }
273 }
274 peopleFlowTypeServiceLoaded = true;
275 return this.peopleFlowTypeService;
276 }
277
278 String getPeopleFlowTypeServiceVersion() {
279 if (!this.peopleFlowTypeServiceLoaded) {
280
281 getPeopleFlowTypeService();
282 }
283
284 return this.peopleFlowTypeServiceVersion;
285 }
286 }
287 }