Coverage Report - org.kuali.student.lum.kim.role.type.KSActionRequestDerivedRoleTypeServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
KSActionRequestDerivedRoleTypeServiceImpl
0%
0/90
0%
0/58
4
KSActionRequestDerivedRoleTypeServiceImpl$REQUESTS_STATUS_TO_CHECK
0%
0/11
0%
0/4
4
KSActionRequestDerivedRoleTypeServiceImpl$REQUESTS_TYPES_TO_CHECK
0%
0/2
N/A
4
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.lum.kim.role.type;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.apache.log4j.Logger;
 20  
 import org.kuali.rice.kew.api.KewApiServiceLocator;
 21  
 import org.kuali.rice.kew.api.action.ActionRequest;
 22  
 import org.kuali.rice.kew.api.action.ActionRequestStatus;
 23  
 import org.kuali.rice.kew.api.document.WorkflowDocumentService;
 24  
 import org.kuali.rice.kew.api.exception.WorkflowException;
 25  
 import org.kuali.rice.kim.api.KimConstants;
 26  
 import org.kuali.rice.kim.api.role.RoleMembership;
 27  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 28  
 import org.kuali.rice.kns.kim.role.DerivedRoleTypeServiceBase;
 29  
 import org.kuali.student.common.rice.StudentIdentityConstants;
 30  
 import org.kuali.student.lum.kim.KimQualificationHelper;
 31  
 
 32  
 import java.util.*;
 33  
 
 34  
 /**
 35  
  *
 36  
  */
 37  0
 public class KSActionRequestDerivedRoleTypeServiceImpl extends DerivedRoleTypeServiceBase {
 38  0
     protected final Logger LOG = Logger.getLogger(getClass());
 39  
         
 40  
         private static final String APPROVE_REQUEST_RECIPIENT_ROLE_CONTENT = "Approve";
 41  
         private static final String ACKNOWLEDGE_REQUEST_RECIPIENT_ROLE_CONTENT = "Acknowledge";
 42  
         private static final String FYI_REQUEST_RECIPIENT_ROLE_CONTENT = "FYI";
 43  0
         private static final String ACTION_REQUEST_INITIALIZED = ActionRequestStatus.INITIALIZED.getCode();
 44  0
         private static final String ACTION_REQUEST_ACTIVATED = ActionRequestStatus.ACTIVATED.getCode();
 45  0
         private static final String ACTION_REQUEST_DONE_STATE = ActionRequestStatus.DONE.getCode();
 46  
         
 47  0
     protected Set<List<String>> newRequiredAttributes = new HashSet<List<String>>();
 48  
 
 49  0
         protected enum REQUESTS_TYPES_TO_CHECK {
 50  0
                 BOTH, ADHOC_ONLY, NON_ADHOC_ONLY;
 51  
         }
 52  
 
 53  0
         protected enum REQUESTS_STATUS_TO_CHECK {
 54  0
                 INITIALIZED(ACTION_REQUEST_INITIALIZED), 
 55  0
                 ACTIVE(ACTION_REQUEST_ACTIVATED), 
 56  0
                 DONE(ACTION_REQUEST_DONE_STATE);
 57  
 
 58  
                 private String kewActionRequestStatusCode;
 59  
 
 60  0
                 private REQUESTS_STATUS_TO_CHECK(String kewActionRequestStatusCode) {
 61  0
                 this.kewActionRequestStatusCode = kewActionRequestStatusCode;
 62  0
         }
 63  
 
 64  
                 public static REQUESTS_STATUS_TO_CHECK getByCode(String code) {
 65  0
                         for (REQUESTS_STATUS_TO_CHECK type : REQUESTS_STATUS_TO_CHECK.values()) {
 66  0
                                 if (type.kewActionRequestStatusCode.equals(code)) {
 67  0
                                         return type;
 68  
                                 }
 69  
                         }
 70  0
                         return null;
 71  
                 }
 72  
         }
 73  
 
 74  
         {
 75  
         // add document number as one required attribute set
 76  0
                 List<String> listOne = new ArrayList<String>();
 77  0
                 listOne.add( KimConstants.AttributeConstants.DOCUMENT_NUMBER );
 78  0
                 newRequiredAttributes.add(listOne);
 79  
         // add document type name and KEW application id as one required attribute set
 80  0
                 List<String> listTwo = new ArrayList<String>();
 81  0
                 listTwo.add( KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME );
 82  0
                 listTwo.add( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID );
 83  0
                 newRequiredAttributes.add(listTwo);
 84  
         // add object id and object type as one required attribute set
 85  0
                 List<String> listThree = new ArrayList<String>();
 86  0
                 listThree.add( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID );
 87  0
                 listThree.add( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE );
 88  0
                 newRequiredAttributes.add(listThree);
 89  
         // add each proposal reference type as a required attribute set
 90  0
         for (String proposalReferenceType : StudentIdentityConstants.QUALIFICATION_PROPOSAL_ID_REF_TYPES) {
 91  0
             List<String> tempList = new ArrayList<String>();
 92  0
             tempList.add( proposalReferenceType );
 93  0
             newRequiredAttributes.add(tempList);
 94  0
         }
 95  0
         }
 96  
 
 97  
         /** 
 98  
          * The part about where the receivedAttributes list being empty does not return errors is copied from Rice base class.
 99  
          * 
 100  
          * @see org.kuali.rice.kim.service.support.impl.KimTypeServiceBase#validateRequiredAttributesAgainstReceived(org.kuali.rice.kim.bo.types.dtoMap<String,String>)
 101  
          **/
 102  
         @Override
 103  
         protected void validateRequiredAttributesAgainstReceived(Map<String,String> receivedAttributes){
 104  0
                 KimQualificationHelper.validateRequiredAttributesAgainstReceived(newRequiredAttributes, receivedAttributes, isCheckRequiredAttributes(), COMMA_SEPARATOR);
 105  0
                 super.validateRequiredAttributesAgainstReceived(receivedAttributes);
 106  0
         }
 107  
 
 108  
     @Override
 109  
     public Map<String,String> translateInputAttributes(Map<String,String> qualification) {
 110  0
         return KimQualificationHelper.translateInputAttributeSet(super.translateInputAttributes(translateInputAttributes(qualification)));
 111  
     }
 112  
 
 113  
         protected String getDocumentNumber(Map<String,String> qualification) throws WorkflowException {
 114  
                 // first check for a valid document id passed in
 115  0
                 String documentId = qualification.get( KimConstants.AttributeConstants.DOCUMENT_NUMBER );
 116  0
         if (StringUtils.isNotEmpty(documentId)) {
 117  0
             return documentId;
 118  
         } else {
 119  0
             LOG.warn("Could not find workflow document id in qualification list:");
 120  0
             LOG.warn(qualification);
 121  0
             return null;
 122  
         }
 123  
 //                if (StringUtils.isNotEmpty(documentId)) {
 124  
 //                        return Long.valueOf(documentId);
 125  
 //                }
 126  
 //                // if no document id passed in get the document via the id and document type name
 127  
 //                String documentTypeName = qualification.get( KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME );
 128  
 //                if (StringUtils.isEmpty(documentTypeName)) {
 129  
 //                        String ksObjectType = qualification.get( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE );
 130  
 //                        if (StringUtils.equals(ksObjectType, "referenceType.clu.proposal")) {
 131  
 //                    documentTypeName = "kuali.proposal.type.course.create";
 132  
 //                        }
 133  
 //                }
 134  
 //                String appId = qualification.get( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID );
 135  
 //                LOG.info("Checking for document id using document type '" + documentTypeName + "' and application id '" + appId + "' with qualifications: " + qualification.toString());
 136  
 //                DocumentDetailDTO docDetail = getWorkflowUtility().getDocumentDetailFromAppId(documentTypeName, appId);
 137  
 //                if (docDetail == null) {
 138  
 //                        LOG.info("No valid document instance found for document type name '" + documentTypeName + "' and Application Id '" + appId + "'");
 139  
 //                        return null;
 140  
 ////                        throw new RuntimeException("No valid document instance found for document type name '" + documentTypeName + "' and Application Id '" + appId + "'");
 141  
 //                }
 142  
 //                return docDetail.getDocumentId();
 143  
         }
 144  
 
 145  
         protected void addMember(Map<String,List<ActionRequest>> requestsByPrincipalId, String principalId, ActionRequest actionRequest) {
 146  0
                 if (!requestsByPrincipalId.containsKey(principalId)) {
 147  0
                         requestsByPrincipalId.put(principalId, new ArrayList<ActionRequest>());
 148  
                 }
 149  0
                 requestsByPrincipalId.get(principalId).add(actionRequest);
 150  0
         }
 151  
 
 152  
         /* (non-Javadoc)
 153  
          * @see org.kuali.rice.kew.role.service.impl.ActionRequestDerivedRoleTypeServiceImpl#getRoleMembersFromDerivedRole(java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.Map<String,String>)
 154  
          */
 155  
         @Override
 156  
         public List<RoleMembership> getRoleMembersFromDerivedRole(
 157  
                         String namespaceCode, String roleName, Map<String,String> paramQualification) {
 158  
                 // validate required attributes
 159  0
                 validateRequiredAttributesAgainstReceived(paramQualification);
 160  0
                 Map<String,String> qualification = translateInputAttributes(paramQualification);
 161  0
                 List<RoleMembership> members = new ArrayList<RoleMembership>();
 162  
                 try {
 163  
                         // check for valid qualification data to check
 164  0
                         String documentNumber = getDocumentNumber(qualification);
 165  0
                         if (documentNumber != null) {
 166  
                                 // get all action requests for the document id given
 167  
                             // TODO: RICE=M7 UPGRADE deal with WorkflowUtility being deprecated
 168  0
                                 List<ActionRequest> actionRequests = getWorkflowDocumentService().getRootActionRequests(documentNumber);
 169  0
                                 Map<String,List<ActionRequest>> requestsByPrincipalId = new HashMap<String, List<ActionRequest>>();
 170  
                                 // build a map by principal id of action requests for the document
 171  0
                     for (ActionRequest actionRequest: actionRequests) {
 172  
                             // if the request has a principal id
 173  0
                             if (actionRequest.getPrincipalId() != null) {
 174  0
                                     addMember(requestsByPrincipalId, actionRequest.getPrincipalId(), actionRequest);
 175  
                             }
 176  
                             // if the request is a group request
 177  0
                             else if (actionRequest.isGroupRequest()) {
 178  0
                                     for (String principalId : KimApiServiceLocator.getGroupService().getMemberPrincipalIds(actionRequest.getGroupId())) {
 179  0
                                             addMember(requestsByPrincipalId, principalId, actionRequest);
 180  
                                                 }
 181  
                             }
 182  
                     }
 183  0
                     for (Map.Entry<String, List<ActionRequest>> mapEntry : requestsByPrincipalId.entrySet()) {
 184  0
                                         if (containsActivatedRequest(roleName, mapEntry.getValue())) {
 185  0
                                 members.add(RoleMembership.Builder.create(null/*roleId*/, null, mapEntry.getKey(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, null).build() );
 186  
                                         }
 187  
                                 }
 188  
                         }
 189  0
                         return members;
 190  0
                 } catch (WorkflowException e) {
 191  0
                         LOG.error("Workflow Error: " + e.getLocalizedMessage(), e);
 192  0
                         throw new RuntimeException("Unable to load route header", e);
 193  
                 }
 194  
         }
 195  
 
 196  
         /* (non-Javadoc)
 197  
          * @see org.kuali.rice.kew.role.service.impl.ActionRequestDerivedRoleTypeServiceImpl#hasDerivedRole(java.lang.String, java.util.List, java.lang.String, java.lang.String, org.kuali.rice.kim.bo.types.dto.Map<String,String>)
 198  
          */
 199  
         @Override
 200  
         public boolean hasDerivedRole(String principalId,
 201  
                         List<String> groupIds, String namespaceCode, String roleName,
 202  
                         Map<String,String> paramQualification) {
 203  0
         validateRequiredAttributesAgainstReceived(paramQualification);
 204  0
         Map<String,String> qualification = translateInputAttributes(paramQualification);
 205  
                 try {
 206  0
                         String documentNumber = getDocumentNumber(qualification);
 207  0
                         if (documentNumber != null) {
 208  0
                                 List<ActionRequest> actionRequests = getWorkflowDocumentService().getActionRequestsForPrincipalAtNode(documentNumber, null, principalId);
 209  0
                                 return containsActivatedRequest(roleName, actionRequests);
 210  
                         }
 211  0
                         return false;
 212  0
                 } catch (WorkflowException e) {
 213  0
                         LOG.error("Workflow Error: " + e.getLocalizedMessage(), e);
 214  0
                         throw new RuntimeException("Unable to load route header", e);
 215  
                 }
 216  
         }
 217  
 
 218  
         protected boolean containsActivatedRequest(String roleName, List<ActionRequest> actionRequests) {
 219  0
                 if (StringUtils.containsIgnoreCase(roleName, APPROVE_REQUEST_RECIPIENT_ROLE_CONTENT)) {
 220  0
                         for ( ActionRequest ar : actionRequests ) {
 221  0
                                 if ( ar.isApprovalRequest() && verifyActionRequest(ar)) {
 222  0
                                         return true;
 223  
                                 }
 224  
                         }
 225  
                 }
 226  0
                 else if (StringUtils.containsIgnoreCase(roleName, ACKNOWLEDGE_REQUEST_RECIPIENT_ROLE_CONTENT)) {
 227  0
                         for ( ActionRequest ar : actionRequests ) {
 228  0
                                 if ( ar.isAcknowledgeRequest() && verifyActionRequest(ar)) {
 229  0
                                         return true;
 230  
                                 }
 231  
                         }
 232  
                 }
 233  0
                 else if (StringUtils.containsIgnoreCase(roleName, FYI_REQUEST_RECIPIENT_ROLE_CONTENT)) {
 234  0
                         for ( ActionRequest ar : actionRequests ) {
 235  0
                                 if ( ar.isFyiRequest() && verifyActionRequest(ar)) {
 236  0
                                         return true;
 237  
                                 }
 238  
                         }
 239  
                 }
 240  0
                 return false;
 241  
         }
 242  
 
 243  
         protected boolean verifyActionRequest(ActionRequest ar) {
 244  0
                 REQUESTS_STATUS_TO_CHECK statusEnum = REQUESTS_STATUS_TO_CHECK.getByCode(ar.getStatus().getCode());
 245  0
                 if (getRequestStatusesToCheck().contains(statusEnum)) {
 246  0
                         if (ar.isAdHocRequest()) {
 247  0
                                 return getRequestTypesToCheck().equals(REQUESTS_TYPES_TO_CHECK.BOTH) || getRequestTypesToCheck().equals(REQUESTS_TYPES_TO_CHECK.ADHOC_ONLY);
 248  
                         }
 249  
                         else {
 250  0
                                 return getRequestTypesToCheck().equals(REQUESTS_TYPES_TO_CHECK.BOTH) || getRequestTypesToCheck().equals(REQUESTS_TYPES_TO_CHECK.NON_ADHOC_ONLY);
 251  
                         }
 252  
                 }
 253  0
                 return false;
 254  
         }
 255  
 
 256  
         /**
 257  
          * Returns false, as the Action Requests change often enough that role membership is highly volatile
 258  
          * 
 259  
          * @see org.kuali.rice.kim.service.support.impl.KimRoleTypeServiceBase#shouldCacheRoleMembershipResults(java.lang.String, java.lang.String)
 260  
          */
 261  
 //        @Override
 262  
         public boolean shouldCacheRoleMembershipResults(String namespaceCode, String roleName) {
 263  0
                 return false;
 264  
         }
 265  
 
 266  
         protected REQUESTS_TYPES_TO_CHECK getRequestTypesToCheck() {
 267  0
                 return REQUESTS_TYPES_TO_CHECK.BOTH;
 268  
         }
 269  
 
 270  
         protected List<REQUESTS_STATUS_TO_CHECK> getRequestStatusesToCheck() {
 271  0
                 return Collections.singletonList(REQUESTS_STATUS_TO_CHECK.ACTIVE);
 272  
         }
 273  
 
 274  
         protected WorkflowDocumentService getWorkflowDocumentService() {
 275  0
                 return KewApiServiceLocator.getWorkflowDocumentService();
 276  
         }
 277  
 }