001/** 002 * Copyright 2004-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.kew.impl.peopleflow; 017 018import org.apache.commons.collections.CollectionUtils; 019import org.apache.commons.lang.StringUtils; 020import org.kuali.rice.core.api.CoreConstants; 021import org.kuali.rice.core.api.config.ConfigurationException; 022import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 023import org.kuali.rice.core.api.exception.RiceIllegalStateException; 024import org.kuali.rice.core.api.membership.MemberType; 025import org.kuali.rice.core.api.util.VersionHelper; 026import org.kuali.rice.kew.actionrequest.ActionRequestFactory; 027import org.kuali.rice.kew.actionrequest.ActionRequestValue; 028import org.kuali.rice.kew.actionrequest.KimGroupRecipient; 029import org.kuali.rice.kew.actionrequest.KimPrincipalRecipient; 030import org.kuali.rice.kew.actionrequest.Recipient; 031import org.kuali.rice.kew.api.action.ActionRequestPolicy; 032import org.kuali.rice.kew.api.action.ActionRequestType; 033import org.kuali.rice.kew.api.action.RecipientType; 034import org.kuali.rice.kew.api.document.Document; 035import org.kuali.rice.kew.api.document.DocumentContent; 036import org.kuali.rice.kew.api.peopleflow.PeopleFlowDefinition; 037import org.kuali.rice.kew.api.peopleflow.PeopleFlowDelegate; 038import org.kuali.rice.kew.api.peopleflow.PeopleFlowMember; 039import org.kuali.rice.kew.api.repository.type.KewTypeDefinition; 040import org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService; 041import org.kuali.rice.kew.engine.RouteContext; 042import org.kuali.rice.kew.framework.peopleflow.PeopleFlowTypeService; 043import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue; 044import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent; 045import org.kuali.rice.kim.api.group.Group; 046import org.kuali.rice.kim.api.identity.principal.Principal; 047import org.kuali.rice.kim.api.role.Role; 048import org.kuali.rice.kim.api.role.RoleMembership; 049import org.kuali.rice.kim.api.role.RoleService; 050import org.kuali.rice.kim.api.services.KimApiServiceLocator; 051import org.kuali.rice.ksb.api.KsbApiServiceLocator; 052import org.kuali.rice.ksb.api.bus.Endpoint; 053 054import javax.xml.namespace.QName; 055import java.util.ArrayList; 056import java.util.Collections; 057import java.util.List; 058import java.util.Map; 059 060/** 061 * Reference implementation of the {@code PeopleFlowRequestGenerator} which is responsible for generating Action 062 * Requests from a {@link PeopleFlowDefinition}. 063 * 064 * @author Kuali Rice Team (rice.collab@kuali.org) 065 */ 066public class PeopleFlowRequestGeneratorImpl implements PeopleFlowRequestGenerator { 067 068 private KewTypeRepositoryService typeRepositoryService; 069 private RoleService roleService; 070 071 @Override 072 public List<ActionRequestValue> generateRequests(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) { 073 Context context = new Context(routeContext, peopleFlow, actionRequested); 074 for (PeopleFlowMember member : peopleFlow.getMembers()) { 075 generateRequestForMember(context, member); 076 } 077 078 return context.getActionRequestFactory().getRequestGraphs(); 079 } 080 081 protected void generateRequestForMember(Context context, PeopleFlowMember member) { 082 // used later for generating any delegate requests 083 List<ActionRequestValue> memberRequests = new ArrayList<ActionRequestValue>(); 084 085 if (MemberType.ROLE == member.getMemberType()) { 086 memberRequests.addAll(findNonRoleRequests(generateRequestsForRoleMember(context, member))); 087 } else { 088 ActionRequestValue actionRequest = context.getActionRequestFactory().addRootActionRequest( 089 context.getActionRequested().getCode(), member.getPriority(), toRecipient(member), "", 090 member.getResponsibilityId(), Boolean.TRUE, getActionRequestPolicyCode(member), null); 091 092 if (actionRequest != null) { 093 memberRequests.add(actionRequest); 094 } 095 } 096 097 // KULRICE-5726: Add support for delegates on roles in PeopleFlows as well as using roles as delegates 098 generateDelegationRequests(context, memberRequests, member); 099 } 100 101 /** 102 * generates requests for a PeopleFlow member of type Role. 103 * 104 * <p>Will resolve role qualifiers through the appropriate PeopleFlowTypeService, and if multiple qualifier maps are 105 * generated, it can generate multiple request trees. 106 * parent requests</p> 107 * 108 * @param context the context for request generation 109 * @param member the PeopleFlow member, which is assumed to be of MemberType ROLE 110 * @return a list of root action requests that were generated, or an empty list if no role members were resolved 111 */ 112 protected List<ActionRequestValue> generateRequestsForRoleMember(Context context, PeopleFlowMember member) { 113 List<ActionRequestValue> roleMemberRequests = new ArrayList<ActionRequestValue>(); // results 114 115 List<Map<String, String>> roleQualifierMaps = loadRoleQualifiers(context, member.getMemberId()); 116 Role role = getRoleService().getRole(member.getMemberId()); 117 118 boolean hasPeopleFlowDelegates = !CollectionUtils.isEmpty(member.getDelegates()); 119 120 if (role == null) { 121 throw new IllegalStateException("Failed to locate a role with the given role id of '" + 122 member.getMemberId() + "'"); 123 } 124 125 if (CollectionUtils.isEmpty(roleQualifierMaps)) { 126 ActionRequestValue request = addKimRoleRequest(context, member, role, Collections.<String, String>emptyMap(), 127 hasPeopleFlowDelegates); 128 129 if (request != null) { 130 roleMemberRequests.add(request); 131 } 132 } else { 133 // we may have multiple maps of role qualifiers, so we'll add a request for each map 134 for (Map<String, String> roleQualifiers : roleQualifierMaps) { 135 ActionRequestValue request = addKimRoleRequest(context, member, role, roleQualifiers, 136 hasPeopleFlowDelegates); 137 if (request != null) { 138 roleMemberRequests.add(request); 139 } 140 } 141 } 142 143 return roleMemberRequests; 144 } 145 146 /** 147 * Uses the ActionRequestFactory to build the request tree for the role members. 148 * 149 * <p>The role members themselves are derived here using the given qualifiers.</p> 150 * 151 * @param context the context for request generation 152 * @param member the PeopleFlow member 153 * @param role the role specified within the member 154 * @param roleQualifiers the qualifiers to use for role member selection 155 * @param ignoreKimDelegates should KIM delegates be ignored when generating requests? 156 * @return the root request of the generated action request tree, or null if no members are found 157 */ 158 private ActionRequestValue addKimRoleRequest(Context context, PeopleFlowMember member, Role role, 159 Map<String, String> roleQualifiers, boolean ignoreKimDelegates) { 160 161 ActionRequestValue roleMemberRequest = null; 162 163 List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList( 164 member.getMemberId()), roleQualifiers); 165 166 String actionRequestPolicyCode = getActionRequestPolicyCode(member); 167 168 if (!CollectionUtils.isEmpty(memberships)) { 169 roleMemberRequest = context.getActionRequestFactory().addKimRoleRequest( 170 context.getActionRequested().getCode(), member.getPriority(), role, memberships, null, 171 member.getResponsibilityId(), true, actionRequestPolicyCode, null, ignoreKimDelegates); 172 //memberships.get(0).getQualifier() 173 } 174 175 return roleMemberRequest; 176 } 177 178 /** 179 * Generates any needed requests for {@link PeopleFlowDelegate}s on the given member. 180 * 181 * <p>If there are no delegates, or if no requests were generated for the member, then this will be a no-op.</p> 182 * 183 * @param context the context for request generation 184 * @param memberRequests any action requests that were generated for the given member 185 * @param member the PeopleFlow member 186 */ 187 private void generateDelegationRequests(Context context, List<ActionRequestValue> memberRequests, 188 PeopleFlowMember member) { 189 190 if (CollectionUtils.isEmpty(member.getDelegates()) || CollectionUtils.isEmpty(memberRequests)) { 191 return; 192 } 193 194 /*for (PeopleFlowDelegate delegate : member.getDelegates()) { 195 if (MemberType.ROLE == delegate.getMemberType()) { 196 generateDelegationToRoleRequests(context, memberRequest, member, delegate); 197 } else { 198 for (ActionRequestValue memberRequest : memberRequests) { 199 generateDelegationToNonRoleRequest(context, memberRequest, member, delegate); 200 } 201 } 202 }*/ 203 /*List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList( 204 member.getMemberId()), roleQualifiers);*/ 205 for (PeopleFlowDelegate delegate : member.getDelegates()) { 206 for (ActionRequestValue memberRequest : memberRequests) { 207 if (MemberType.ROLE == delegate.getMemberType()) { 208 generateDelegationToRoleRequests(context, memberRequest, member, delegate); 209 } else { 210 generateDelegationToNonRoleRequest(context, memberRequest, member, delegate); 211 } 212 } 213 } 214 } 215 216 /** 217 * Uses the ActionRequestFactory to add the delegate request to the given parent request. 218 * 219 * <p>Only handles non-role delegates. If a delegate of type role is passed, a RiceIllegalStateException will be 220 * thrown.</p> 221 * 222 * @param context the context for request generation 223 * @param memberRequest an action request that was generated for the given member 224 * @param member the PeopleFlow member 225 * @param delegate the delegate to generate a request to 226 */ 227 private void generateDelegationToNonRoleRequest(Context context, ActionRequestValue memberRequest, 228 PeopleFlowMember member, PeopleFlowDelegate delegate) { 229 230 Recipient recipient; 231 232 if (MemberType.PRINCIPAL == delegate.getMemberType()) { 233 recipient = new KimPrincipalRecipient(delegate.getMemberId()); 234 } else if (MemberType.GROUP == delegate.getMemberType()) { 235 recipient = new KimGroupRecipient(delegate.getMemberId()); 236 } else { 237 throw new RiceIllegalStateException("MemberType unknown: " + delegate.getMemberType()); 238 } 239 240 String actionRequestPolicyCode = getDelegateActionRequestPolicyCode(member, delegate); 241 242 String delegationAnnotation = generateDelegationAnnotation(memberRequest, member, delegate); 243 244 context.getActionRequestFactory().addDelegationRequest(memberRequest, recipient, 245 delegate.getResponsibilityId(), memberRequest.getForceAction(), 246 delegate.getDelegationType(), actionRequestPolicyCode, delegationAnnotation, null); 247 } 248 249 /** 250 * Builds the String that will be used for the annotation on the delegate requests 251 * 252 * @param parentRequest an action request that was generated for the given member 253 * @param member the PeopleFlow member 254 * @param delegate the delegate 255 * @return the annotation string 256 */ 257 private String generateDelegationAnnotation(ActionRequestValue parentRequest, PeopleFlowMember member, 258 PeopleFlowDelegate delegate) { 259 260 StringBuffer annotation = new StringBuffer( "Delegation of: " ); 261 annotation.append( parentRequest.getAnnotation() ); 262 annotation.append( " to " ); 263 264 if (delegate.getMemberType() == MemberType.PRINCIPAL) { 265 annotation.append( "principal " ); 266 Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(delegate.getMemberId()); 267 268 if ( principal != null ) { 269 annotation.append( principal.getPrincipalName() ); 270 } else { 271 annotation.append( member.getMemberId() ); 272 } 273 } else if (delegate.getMemberType() == MemberType.GROUP) { 274 annotation.append( "group " ); 275 Group group = KimApiServiceLocator.getGroupService().getGroup(delegate.getMemberId()); 276 277 if ( group != null ) { 278 annotation.append( group.getNamespaceCode() ).append( '/' ).append( group.getName() ); 279 } else { 280 annotation.append( member.getMemberId() ); 281 } 282 } else { 283 annotation.append( "?????? '" ); 284 annotation.append( member.getMemberId() ); 285 annotation.append( "'" ); 286 } 287 288 return annotation.toString(); 289 } 290 291 292 /** 293 * Generates any needed requests for the given {@link PeopleFlowDelegate}. 294 * 295 * <p>It is assumed that the given member has the given delegate configured.</p> 296 * 297 * @param context the context for request generation 298 * @param parentRequest an action request that was generated for the given member 299 * @param member the PeopleFlow member, which should contain the given delegate 300 * @param delegate the delegate, assumed to be of MemberType ROLE, to generate a request to 301 */ 302 protected void generateDelegationToRoleRequests(Context context, 303 ActionRequestValue parentRequest, PeopleFlowMember member, PeopleFlowDelegate delegate) { 304 305 List<Map<String, String>> roleQualifierList = loadRoleQualifiers(context, delegate.getMemberId()); 306 Role role = getRoleService().getRole(delegate.getMemberId()); 307 308 if (role == null) { 309 throw new IllegalStateException("Failed to locate a role with the given role id of '" + 310 delegate.getMemberId() + "'"); 311 } 312 313 if (CollectionUtils.isEmpty(roleQualifierList)) { 314 addKimRoleDelegateRequest(context, parentRequest, member, delegate, role, 315 Collections.<String, String>emptyMap()); 316 } else { 317 for (Map<String, String> roleQualifiers : roleQualifierList) { 318 List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList( 319 member.getMemberId()), roleQualifiers); 320 for (RoleMembership membership : memberships) { 321 if (membership.getType().equals(MemberType.PRINCIPAL) 322 && StringUtils.equals(membership.getMemberId(), parentRequest.getPrincipalId())) { 323 addKimRoleDelegateRequest(context, parentRequest, member, delegate, role, roleQualifiers); 324 } else if (membership.getType().equals(MemberType.GROUP) 325 && StringUtils.equals(membership.getMemberId(), parentRequest.getGroupId())) { 326 addKimRoleDelegateRequest(context, parentRequest, member, delegate, role, roleQualifiers); 327 } 328 } 329 330 } 331 } 332 } 333 334 /** 335 * Helper method uses the ActionRequestFactory to add to the parent request the delegation request(s) to a role. 336 * 337 * <p>The role members themselves are derived here using the given qualifiers.</p> 338 * 339 * @param context the context for request generation 340 * @param parentRequest an action request that was generated for the given member 341 * @param member the PeopleFlow member 342 * @param delegate the delegate to generate a request to 343 * @param role the role specified within the delegate 344 * @param roleQualifiers the qualifiers to use for role member selection 345 */ 346 private void addKimRoleDelegateRequest(Context context, ActionRequestValue parentRequest, 347 PeopleFlowMember member, PeopleFlowDelegate delegate, Role role, Map<String, String> roleQualifiers) { 348 349 // sanity check 350 if (delegate.getMemberType() != MemberType.ROLE) { 351 throw new RiceIllegalArgumentException("delegate's member type must be ROLE"); 352 } else if (!delegate.getMemberId().equals(role.getId())) { 353 throw new RiceIllegalArgumentException("delegate's member id must match the given role's id"); 354 } 355 356 String actionRequestPolicyCode = getDelegateActionRequestPolicyCode(member, delegate); 357 358 List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList( 359 delegate.getMemberId()), roleQualifiers); 360 361 if (!CollectionUtils.isEmpty(memberships)) { 362 context.getActionRequestFactory().addDelegateKimRoleRequest(parentRequest, 363 delegate.getDelegationType(), context.getActionRequested().getCode(), member.getPriority(), role, 364 memberships, null, delegate.getResponsibilityId(), true, actionRequestPolicyCode, null); 365 } 366 } 367 368 /** 369 * Uses the appropriate {@link PeopleFlowTypeService} to get the role qualifier maps for the given document and 370 * role. 371 * 372 * <p>Note that the PeopleFlowTypeService is selected based on the type id of the PeopleFlow.</p> 373 * 374 * @param context the context for request generation 375 * @param roleId the ID of the role for whom qualifiers are being loaded 376 * @return the qualifier maps, or an empty list if there are none 377 */ 378 protected List<Map<String, String>> loadRoleQualifiers(Context context, String roleId) { 379 PeopleFlowTypeService peopleFlowTypeService = context.getPeopleFlowTypeService(); 380 List<Map<String, String>> roleQualifierList = new ArrayList<Map<String, String>>(); 381 382 if (peopleFlowTypeService != null) { 383 Document document = DocumentRouteHeaderValue.to(context.getRouteContext().getDocument()); 384 DocumentRouteHeaderValueContent content = new DocumentRouteHeaderValueContent(document.getDocumentId()); 385 content.setDocumentContent(context.getRouteContext().getDocumentContent().getDocContent()); 386 DocumentContent documentContent = DocumentRouteHeaderValueContent.to(content); 387 388 Map<String, String> roleQualifiers = peopleFlowTypeService.resolveRoleQualifiers( 389 context.getPeopleFlow().getTypeId(), roleId, document, documentContent 390 ); 391 392 if (roleQualifiers != null) { 393 roleQualifierList.add(roleQualifiers); 394 } 395 396 boolean versionOk = VersionHelper.compareVersion(context.getPeopleFlowTypeServiceVersion(), CoreConstants.Versions.VERSION_2_3_0) != -1; 397 if(versionOk) { 398 List<Map<String, String>> multipleRoleQualifiers = peopleFlowTypeService.resolveMultipleRoleQualifiers( 399 context.getPeopleFlow().getTypeId(), roleId, document, documentContent); 400 401 if (multipleRoleQualifiers != null) { 402 roleQualifierList.addAll(multipleRoleQualifiers); 403 } 404 } 405 406 } 407 408 return roleQualifierList; 409 } 410 411 /** 412 * Gets the action request policy code for the given delegate. 413 * 414 * <p>the delegate is considered first, and the member is used as a fallback. May return null.</p> 415 * 416 * @param member the PeopleFlow member 417 * @param delegate the delegate 418 * @return the action request policy code, or null if none is found 419 */ 420 private String getDelegateActionRequestPolicyCode(PeopleFlowMember member, PeopleFlowDelegate delegate) { 421 ActionRequestPolicy actionRequestPolicy = delegate.getActionRequestPolicy(); 422 423 return (actionRequestPolicy != null) ? actionRequestPolicy.getCode() : getActionRequestPolicyCode(member); 424 } 425 426 /** 427 * Gets the action request policy code for the given member. 428 * 429 * @param member the PeopleFlow member 430 * @return the action request policy code, or null if none is found 431 */ 432 private String getActionRequestPolicyCode(PeopleFlowMember member) { 433 ActionRequestPolicy actionRequestPolicy = member.getActionRequestPolicy(); 434 435 return (actionRequestPolicy != null) ? actionRequestPolicy.getCode() : null; 436 } 437 438 private Recipient toRecipient(PeopleFlowMember member) { 439 Recipient recipient; 440 if (MemberType.PRINCIPAL == member.getMemberType()) { 441 recipient = new KimPrincipalRecipient(member.getMemberId()); 442 } else if (MemberType.GROUP == member.getMemberType()) { 443 recipient = new KimGroupRecipient(member.getMemberId()); 444 } else { 445 throw new IllegalStateException("encountered a member type which I did not understand: " + 446 member.getMemberType()); 447 } 448 return recipient; 449 } 450 451 private Recipient toRecipient(PeopleFlowDelegate delegate) { 452 Recipient recipient; 453 if (MemberType.PRINCIPAL == delegate.getMemberType()) { 454 recipient = new KimPrincipalRecipient(delegate.getMemberId()); 455 } else if (MemberType.GROUP == delegate.getMemberType()) { 456 recipient = new KimGroupRecipient(delegate.getMemberId()); 457 } else { 458 throw new IllegalStateException("encountered a delegate member type which I did not understand: " + 459 delegate.getMemberType()); 460 } 461 return recipient; 462 } 463 464 public KewTypeRepositoryService getTypeRepositoryService() { 465 return typeRepositoryService; 466 } 467 468 public void setTypeRepositoryService(KewTypeRepositoryService typeRepositoryService) { 469 this.typeRepositoryService = typeRepositoryService; 470 } 471 472 public RoleService getRoleService() { 473 return roleService; 474 } 475 476 public void setRoleService(RoleService roleService) { 477 this.roleService = roleService; 478 } 479 480 /** 481 * Recursively find all non-delegate Group and Principal requests from all of the requests in the given list. 482 * 483 * @param actionRequestValues the list of {@link ActionRequestValue}s to search 484 * @return a list of the non-delegate Group and Principal requests found 485 */ 486 private List<ActionRequestValue> findNonRoleRequests(List<ActionRequestValue> actionRequestValues) { 487 List<ActionRequestValue> nonRoleRequests = new ArrayList<ActionRequestValue>(); 488 489 return findNonRoleRequests(actionRequestValues, nonRoleRequests); 490 } 491 492 // Recursion helper method 493 private List<ActionRequestValue> findNonRoleRequests(List<ActionRequestValue> actionRequestValues, 494 List<ActionRequestValue> nonRoleRequests) { 495 496 if (!CollectionUtils.isEmpty(actionRequestValues)) { 497 for (ActionRequestValue request : actionRequestValues) if (request.getDelegationType() == null) { 498 if (!CollectionUtils.isEmpty(request.getChildrenRequests())) { 499 findNonRoleRequests(request.getChildrenRequests(), nonRoleRequests); 500 } else { 501 // see if we have a principal request 502 if (RecipientType.ROLE.getCode() != request.getRecipientTypeCd()) { 503 nonRoleRequests.add(request); 504 } 505 } 506 } 507 } 508 509 return nonRoleRequests; 510 } 511 512 513 /** 514 * A simple class used to hold context during the PeopleFlow action request generation process. Construction of 515 * the context will validate that the given values are valid, non-null values where appropriate. 516 */ 517 final class Context { 518 519 private final RouteContext routeContext; 520 private final PeopleFlowDefinition peopleFlow; 521 private final ActionRequestType actionRequested; 522 private final ActionRequestFactory actionRequestFactory; 523 524 // lazily loaded 525 private PeopleFlowTypeService peopleFlowTypeService; 526 private boolean peopleFlowTypeServiceLoaded = false; 527 private String peopleFlowTypeServiceVersion; 528 529 Context(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) { 530 if (routeContext == null) { 531 throw new IllegalArgumentException("routeContext was null"); 532 } 533 if (peopleFlow == null) { 534 throw new IllegalArgumentException("peopleFlow was null"); 535 } 536 if (!peopleFlow.isActive()) { 537 throw new ConfigurationException("Attempted to route to a PeopleFlow that is not active! " + peopleFlow); 538 } 539 if (actionRequested == null) { 540 actionRequested = ActionRequestType.APPROVE; 541 } 542 this.routeContext = routeContext; 543 this.peopleFlow = peopleFlow; 544 this.actionRequested = actionRequested; 545 this.actionRequestFactory = new ActionRequestFactory(routeContext); 546 } 547 548 RouteContext getRouteContext() { 549 return routeContext; 550 } 551 552 PeopleFlowDefinition getPeopleFlow() { 553 return peopleFlow; 554 } 555 556 ActionRequestType getActionRequested() { 557 return actionRequested; 558 } 559 560 ActionRequestFactory getActionRequestFactory() { 561 return actionRequestFactory; 562 } 563 564 /** 565 * Lazily loads and caches the {@code PeopleFlowTypeService} (if necessary) and returns it. 566 */ 567 PeopleFlowTypeService getPeopleFlowTypeService() { 568 if (peopleFlowTypeServiceLoaded) { 569 return this.peopleFlowTypeService; 570 } 571 572 if (getPeopleFlow().getTypeId() != null) { 573 KewTypeDefinition typeDefinition = getTypeRepositoryService().getTypeById(getPeopleFlow().getTypeId()); 574 575 if (typeDefinition == null) { 576 throw new IllegalStateException("Failed to locate a PeopleFlow type for the given type id of '" + getPeopleFlow().getTypeId() + "'"); 577 } 578 579 if (StringUtils.isNotBlank(typeDefinition.getServiceName())) { 580 Endpoint endpoint = KsbApiServiceLocator.getServiceBus().getEndpoint(QName.valueOf(typeDefinition.getServiceName())); 581 582 if (endpoint == null) { 583 throw new IllegalStateException("Failed to load the PeopleFlowTypeService with the name '" + typeDefinition.getServiceName() + "'"); 584 } 585 586 this.peopleFlowTypeService = (PeopleFlowTypeService)endpoint.getService(); 587 this.peopleFlowTypeServiceVersion = endpoint.getServiceConfiguration().getServiceVersion(); 588 } 589 } 590 peopleFlowTypeServiceLoaded = true; 591 return this.peopleFlowTypeService; 592 } 593 594 String getPeopleFlowTypeServiceVersion() { 595 if (!this.peopleFlowTypeServiceLoaded) { 596 // execute getPeopleFlowTypeService first to lazy load 597 getPeopleFlowTypeService(); 598 } 599 600 return this.peopleFlowTypeServiceVersion; 601 } 602 } 603}