Coverage Report - org.kuali.rice.kew.impl.peopleflow.PeopleFlowRequestGeneratorImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
PeopleFlowRequestGeneratorImpl
0%
0/52
0%
0/26
3
PeopleFlowRequestGeneratorImpl$Context
0%
0/31
0%
0/18
3
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 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  
  * Reference implementation of the {@code PeopleFlowRequestGenerator} which is responsible for generating Action
 51  
  * Requests from a {@link PeopleFlowDefinition}.
 52  
  *
 53  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 54  
  */
 55  0
 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  0
         Context context = new Context(routeContext, peopleFlow, actionRequested);
 63  0
         for (PeopleFlowMember member : peopleFlow.getMembers()) {
 64  0
             generateRequestForMember(context, member);
 65  
         }
 66  0
         return context.getActionRequestFactory().getRequestGraphs();
 67  
     }
 68  
 
 69  
     protected void generateRequestForMember(Context context, PeopleFlowMember member) {
 70  0
         String actionRequestPolicyCode = null;
 71  0
         if (member.getActionRequestPolicy() != null) {
 72  0
             actionRequestPolicyCode = member.getActionRequestPolicy().getCode();
 73  
         }
 74  0
         if (MemberType.ROLE == member.getMemberType()) {
 75  0
             generateRequestForRoleMember(context, member, actionRequestPolicyCode);
 76  
         } else {
 77  0
             ActionRequestValue actionRequest = context.getActionRequestFactory().addRootActionRequest(
 78  
                     context.getActionRequested().getCode(), member.getPriority(), toRecipient(member), "",
 79  
                     member.getResponsibilityId(), Boolean.TRUE, actionRequestPolicyCode, null);
 80  0
             if (CollectionUtils.isNotEmpty(member.getDelegates())) {
 81  0
                 for (PeopleFlowDelegate delegate : member.getDelegates()) {
 82  0
                     context.getActionRequestFactory().addDelegationRequest(actionRequest, toRecipient(delegate),
 83  
                             delegate.getResponsibilityId(), Boolean.TRUE, delegate.getDelegationType(), "", null);
 84  
                 }
 85  
             }
 86  
         }
 87  0
     }
 88  
 
 89  
     protected void generateRequestForRoleMember(Context context, PeopleFlowMember member, String actionRequestPolicyCode) {
 90  0
         Map<String, String> roleQualifiers = loadRoleQualifiers(context, member);
 91  0
         Role role = getRoleService().getRole(member.getMemberId());
 92  0
         if (role == null) {
 93  0
             throw new IllegalStateException("Failed to locate a role with the given role id of '" + member.getMemberId() + "'");
 94  
         }
 95  0
         List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList(
 96  
                 member.getMemberId()), roleQualifiers);
 97  0
         if (!CollectionUtils.isEmpty(memberships)) {
 98  0
             context.getActionRequestFactory().addKimRoleRequest(context.getActionRequested().getCode(), member.getPriority(),
 99  
                     role, memberships, null, member.getResponsibilityId(), true, actionRequestPolicyCode, null);
 100  
         }
 101  
         // TODO - KULRICE-5726 - still need to implement support for ignoring built-in kim delegates whenever peopleflow delegate(s) are defined
 102  0
     }
 103  
 
 104  
     protected Map<String, String> loadRoleQualifiers(Context context, PeopleFlowMember member) {
 105  0
         PeopleFlowTypeService peopleFlowTypeService = context.getPeopleFlowTypeService();
 106  0
         if (peopleFlowTypeService != null) {
 107  0
             Document document = DocumentRouteHeaderValue.to(context.getRouteContext().getDocument());
 108  0
             DocumentRouteHeaderValueContent content = new DocumentRouteHeaderValueContent(document.getDocumentId());
 109  0
             content.setDocumentContent(context.getRouteContext().getDocumentContent().getDocContent());
 110  0
             DocumentContent documentContent = DocumentRouteHeaderValueContent.to(content);
 111  0
             Map<String, String> roleQualifiers = peopleFlowTypeService.resolveRoleQualifiers(
 112  
                     context.getPeopleFlow().getTypeId(), member.getMemberId(), document, documentContent);
 113  0
             if (roleQualifiers != null) {
 114  0
                 return roleQualifiers;
 115  
             }
 116  
         }
 117  0
         return Collections.emptyMap();
 118  
     }
 119  
 
 120  
     private Recipient toRecipient(PeopleFlowMember member) {
 121  
         Recipient recipient;
 122  0
         if (MemberType.PRINCIPAL == member.getMemberType()) {
 123  0
             recipient = new KimPrincipalRecipient(member.getMemberId());
 124  0
         } else if (MemberType.GROUP == member.getMemberType()) {
 125  0
             recipient = new KimGroupRecipient(member.getMemberId());
 126  
         } else {
 127  0
             throw new IllegalStateException("encountered a member type which I did not understand: " +
 128  
                     member.getMemberType());
 129  
         }
 130  0
         return recipient;
 131  
     }
 132  
 
 133  
     private Recipient toRecipient(PeopleFlowDelegate delegate) {
 134  
         Recipient recipient;
 135  0
         if (MemberType.PRINCIPAL == delegate.getMemberType()) {
 136  0
             recipient = new KimPrincipalRecipient(delegate.getMemberId());
 137  0
         } else if (MemberType.GROUP == delegate.getMemberType()) {
 138  0
             recipient = new KimGroupRecipient(delegate.getMemberId());
 139  
         } else {
 140  0
             throw new IllegalStateException("encountered a delegate member type which I did not understand: " +
 141  
                     delegate.getMemberType());
 142  
         }
 143  0
         return recipient;
 144  
     }
 145  
 
 146  
     public KewTypeRepositoryService getTypeRepositoryService() {
 147  0
         return typeRepositoryService;
 148  
     }
 149  
 
 150  
     public void setTypeRepositoryService(KewTypeRepositoryService typeRepositoryService) {
 151  0
         this.typeRepositoryService = typeRepositoryService;
 152  0
     }
 153  
 
 154  
     public RoleService getRoleService() {
 155  0
         return roleService;
 156  
     }
 157  
 
 158  
     public void setRoleService(RoleService roleService) {
 159  0
         this.roleService = roleService;
 160  0
     }
 161  
 
 162  
     /**
 163  
      * A simple class used to hold context during the PeopleFlow action request generation process.  Construction of
 164  
      * the context will validate that the given values are valid, non-null values where appropriate.
 165  
      */
 166  0
     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  
         // lazily loaded
 174  
         private PeopleFlowTypeService peopleFlowTypeService;
 175  0
         private boolean peopleFlowTypeServiceLoaded = false;
 176  
 
 177  0
         Context(RouteContext routeContext, PeopleFlowDefinition peopleFlow, ActionRequestType actionRequested) {
 178  0
             if (routeContext == null) {
 179  0
                 throw new IllegalArgumentException("routeContext was null");
 180  
             }
 181  0
             if (peopleFlow == null) {
 182  0
                 throw new IllegalArgumentException("peopleFlow was null");
 183  
             }
 184  0
             if (!peopleFlow.isActive()) {
 185  0
                 throw new ConfigurationException("Attempted to route to a PeopleFlow that is not active! " + peopleFlow);
 186  
             }
 187  0
             if (actionRequested == null) {
 188  0
                 actionRequested = ActionRequestType.APPROVE;
 189  
             }
 190  0
             this.routeContext = routeContext;
 191  0
             this.peopleFlow = peopleFlow;
 192  0
             this.actionRequested = actionRequested;
 193  0
             this.actionRequestFactory = new ActionRequestFactory(routeContext);
 194  0
         }
 195  
 
 196  
         RouteContext getRouteContext() {
 197  0
             return routeContext;
 198  
         }
 199  
 
 200  
         PeopleFlowDefinition getPeopleFlow() {
 201  0
             return peopleFlow;
 202  
         }
 203  
 
 204  
         ActionRequestType getActionRequested() {
 205  0
             return actionRequested;
 206  
         }
 207  
 
 208  
         ActionRequestFactory getActionRequestFactory() {
 209  0
             return actionRequestFactory;
 210  
         }
 211  
 
 212  
         /**
 213  
          * Lazily loads and caches the {@code PeopleFlowTypeService} (if necessary) and returns it.
 214  
          */
 215  
         PeopleFlowTypeService getPeopleFlowTypeService() {
 216  0
             if (peopleFlowTypeServiceLoaded) {
 217  0
                 return this.peopleFlowTypeService;
 218  
             }
 219  0
             if (getPeopleFlow().getTypeId() != null) {
 220  0
                 KewTypeDefinition typeDefinition = getTypeRepositoryService().getTypeById(getPeopleFlow().getTypeId());
 221  0
                 if (typeDefinition == null) {
 222  0
                     throw new IllegalStateException("Failed to locate a PeopleFlow type for the given type id of '" + getPeopleFlow().getTypeId() + "'");
 223  
                 }
 224  0
                 if (StringUtils.isNotBlank(typeDefinition.getServiceName())) {
 225  0
                     this.peopleFlowTypeService = GlobalResourceLoader.getService(QName.valueOf(typeDefinition.getServiceName()));
 226  0
                     if (this.peopleFlowTypeService == null) {
 227  0
                         throw new IllegalStateException("Failed to load the PeopleFlowTypeService with the name '" + typeDefinition.getServiceName() + "'");
 228  
                      }
 229  
                 }
 230  
             }
 231  0
             peopleFlowTypeServiceLoaded = true;
 232  0
             return this.peopleFlowTypeService;
 233  
         }
 234  
 
 235  
     }
 236  
 }