View Javadoc

1   package org.kuali.student.lum.workflow;
2   
3   import javax.xml.namespace.QName;
4   
5   import org.apache.commons.lang.StringUtils;
6   import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
7   import org.kuali.rice.kew.api.KewApiConstants;
8   import org.kuali.rice.kew.api.action.ActionTaken;
9   import org.kuali.rice.kew.framework.postprocessor.ActionTakenEvent;
10  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
11  import org.kuali.student.r2.core.atp.service.AtpService;
12  import org.kuali.student.r2.common.dto.DtoConstants;
13  import org.kuali.student.r2.common.exceptions.OperationFailedException;
14  import org.kuali.student.r2.common.util.AttributeHelper;
15  import org.kuali.student.r2.common.util.ContextUtils;
16  import org.kuali.student.r2.common.util.constants.ProgramServiceConstants;
17  import org.kuali.student.r2.core.proposal.dto.ProposalInfo;
18  import org.kuali.student.r2.lum.program.service.ProgramService;
19  import org.springframework.transaction.annotation.Transactional;
20  
21  @Transactional(readOnly=true, rollbackFor={Throwable.class})
22  public class ProgramPostProcessorBase extends KualiStudentPostProcessorBase {
23      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProgramPostProcessorBase.class);
24  
25      private ProgramService programService;
26  	private StateChangeService stateChangeService;
27  
28      @Override
29      protected void processWithdrawActionTaken(ActionTakenEvent actionTakenEvent, ProposalInfo proposalInfo) throws Exception {
30          LOG.info("Will set CLU state to '" + DtoConstants.STATE_DRAFT + "'");
31          String programId = getProgramId(proposalInfo);
32          getStateChangeService().changeState(programId, DtoConstants.STATE_DRAFT, ContextUtils.getContextInfo());
33      }
34  
35      @Override
36      protected boolean processCustomActionTaken(ActionTakenEvent actionTakenEvent,  ActionTaken actionTaken, ProposalInfo proposalInfo) throws Exception {
37      	//TODO Why is this method implemented in course post processor? it might be important for program as well
38          return true;
39      }
40  
41      @Override
42      protected boolean processCustomRouteStatusChange(DocumentRouteStatusChange statusChangeEvent, ProposalInfo proposalInfo) throws Exception {
43          // update the program state based on the route status
44      	// Mainly used to approve a proposal
45          String programId = getProgramId(proposalInfo);
46          String endEntryTerm = new AttributeHelper (proposalInfo.getAttributes()).get("prevEndProgramEntryTerm");
47          String endEnrollTerm = new AttributeHelper (proposalInfo.getAttributes()).get("prevEndTerm");
48          String endInstAdmitTerm = new AttributeHelper (proposalInfo.getAttributes()).get("prevEndInstAdmitTerm");
49          getStateChangeService().changeState(endEntryTerm, endEnrollTerm, endInstAdmitTerm, programId, getCluStateForRouteStatus("",statusChangeEvent.getNewRouteStatus()), ContextUtils.getContextInfo());
50          return true;
51      }
52  
53      protected String getProgramId(ProposalInfo proposalInfo) throws OperationFailedException {
54          if (proposalInfo.getProposalReference().size() != 1) {
55              LOG.error("Found " + proposalInfo.getProposalReference().size() + " CLU objects linked to proposal with proposalId='" + proposalInfo.getId() + "'. Must have exactly 1 linked.");
56              throw new OperationFailedException("Found " + proposalInfo.getProposalReference().size() + " CLU objects linked to proposal with docId='" + proposalInfo.getWorkflowId() + "' and proposalId='" + proposalInfo.getId() + "'. Must have exactly 1 linked.");
57          }
58          return proposalInfo.getProposalReference().get(0);
59      }
60  
61      /**
62       * @param currentCluState - the current state set on the CLU
63       * @param newWorkflowStatusCode - the new route status code that is getting set on the workflow document
64       * @return the CLU state to set or null if the CLU does not need it's state changed
65       */
66      protected String getCluStateForRouteStatus(String currentCluState, String newWorkflowStatusCode) {
67          if (StringUtils.equals(KewApiConstants.ROUTE_HEADER_SAVED_CD, newWorkflowStatusCode)) {
68              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
69          } else if (KewApiConstants.ROUTE_HEADER_CANCEL_CD .equals(newWorkflowStatusCode)) {
70              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_NOT_APPROVED);
71          } else if (KewApiConstants.ROUTE_HEADER_ENROUTE_CD.equals(newWorkflowStatusCode)) {
72              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
73          } else if (KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD.equals(newWorkflowStatusCode)) {
74              /* current requirements state that on a Withdraw (which is a KEW Disapproval) the 
75               * CLU state should be submitted so no special handling required here
76               */
77              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_NOT_APPROVED);
78          } else if (KewApiConstants.ROUTE_HEADER_PROCESSED_CD.equals(newWorkflowStatusCode)) {
79              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_ACTIVE);
80          } else if (KewApiConstants.ROUTE_HEADER_EXCEPTION_CD.equals(newWorkflowStatusCode)) {
81              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
82          } else {
83              // no status to set
84              return null;
85          }
86      }
87  
88      /**
89       * Default behavior is to return the <code>newCluState</code> variable only if it differs from the
90       * <code>currentCluState</code> value. Otherwise <code>null</code> will be returned.
91       */
92      protected String getCourseStateFromNewState(String currentCourseState, String newCourseState) {
93          if (LOG.isInfoEnabled()) {
94              LOG.info("current CLU state is '" + currentCourseState + "' and new CLU state will be '" + newCourseState + "'");
95          }
96          return getStateFromNewState(currentCourseState, newCourseState);
97      }
98  
99  
100     protected ProgramService getProgramService() {
101         if (this.programService == null) {
102             this.programService = (ProgramService) GlobalResourceLoader.getService(new QName(ProgramServiceConstants.PROGRAM_NAMESPACE,"ProgramService")); 
103         }
104         return this.programService;
105     }
106     
107     
108     protected StateChangeService getStateChangeService() {
109         if (this.stateChangeService == null) {
110         	MajorDisciplineStateChangeServiceImpl stateChangeService = new MajorDisciplineStateChangeServiceImpl();
111             stateChangeService.setProgramService(getProgramService());
112             stateChangeService.setAtpService((AtpService)GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/atp","AtpService")));
113             this.stateChangeService = stateChangeService;
114         }
115         
116         return this.stateChangeService;
117     }
118 }