1   
2   
3   
4   package org.kuali.student.lum.workflow;
5   
6   import java.util.Iterator;
7   import java.util.List;
8   
9   import javax.xml.namespace.QName;
10  
11  import org.apache.commons.lang.StringUtils;
12  import org.kuali.rice.core.resourceloader.GlobalResourceLoader;
13  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
14  import org.kuali.rice.kew.postprocessor.ActionTakenEvent;
15  import org.kuali.rice.kew.postprocessor.DocumentRouteStatusChange;
16  import org.kuali.rice.kew.postprocessor.IDocumentEvent;
17  import org.kuali.rice.kew.util.KEWConstants;
18  import org.kuali.student.common.dto.DtoConstants;
19  import org.kuali.student.common.exceptions.DoesNotExistException;
20  import org.kuali.student.common.exceptions.OperationFailedException;
21  import org.kuali.student.core.proposal.dto.ProposalInfo;
22  import org.kuali.student.core.statement.dto.ReqComponentInfo;
23  import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
24  import org.kuali.student.lum.course.dto.CourseInfo;
25  import org.kuali.student.lum.course.service.CourseService;
26  import org.springframework.transaction.annotation.Transactional;
27  
28  
29  
30  
31  
32  @Transactional(readOnly=true, rollbackFor={Throwable.class})
33  public class CoursePostProcessorBase extends KualiStudentPostProcessorBase {
34      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CoursePostProcessorBase.class);
35  
36      private CourseService courseService;
37      private CourseStateChangeServiceImpl courseStateChangeService;
38      
39      @Override
40      protected void processWithdrawActionTaken(ActionTakenEvent actionTakenEvent, ProposalInfo proposalInfo) throws Exception {
41          LOG.info("Will set CLU state to '" + DtoConstants.STATE_NOT_APPROVED + "'");
42          CourseInfo courseInfo = getCourseService().getCourse(getCourseId(proposalInfo));
43          updateCourse(actionTakenEvent, DtoConstants.STATE_NOT_APPROVED, courseInfo);
44      }
45  
46      @Override
47      protected boolean processCustomActionTaken(ActionTakenEvent actionTakenEvent, ActionTakenValue actionTaken, ProposalInfo proposalInfo) throws Exception {
48          String cluId = getCourseId(proposalInfo);
49          CourseInfo courseInfo = getCourseService().getCourse(cluId);
50          
51          updateCourse(actionTakenEvent, null, courseInfo);
52          return true;
53      }
54  
55      @Override
56      protected boolean processCustomRouteStatusChange(DocumentRouteStatusChange statusChangeEvent, ProposalInfo proposalInfo) throws Exception {
57          
58          String courseId = getCourseId(proposalInfo);
59          String prevEndTermAtpId = proposalInfo.getAttributes().get("prevEndTerm");
60          CourseInfo courseInfo = getCourseService().getCourse(courseId);
61          String courseState = getCluStateForRouteStatus(courseInfo.getState(), statusChangeEvent.getNewRouteStatus());
62          
63          if(DtoConstants.STATE_ACTIVE.equals(courseState)){
64          	
65          	getCourseStateChangeService().changeState(courseId, courseState, prevEndTermAtpId);
66          }else{
67          	updateCourse(statusChangeEvent, courseState, courseInfo);
68          }
69          return true;
70      }
71  
72      protected String getCourseId(ProposalInfo proposalInfo) throws OperationFailedException {
73          if (proposalInfo.getProposalReference().size() != 1) {
74              LOG.error("Found " + proposalInfo.getProposalReference().size() + " CLU objects linked to proposal with proposalId='" + proposalInfo.getId() + "'. Must have exactly 1 linked.");
75              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.");
76          }
77          return proposalInfo.getProposalReference().get(0);
78      }
79  
80      
81  
82  
83  
84  
85      protected String getCluStateForRouteStatus(String currentCluState, String newWorkflowStatusCode) {
86          if (StringUtils.equals(KEWConstants.ROUTE_HEADER_SAVED_CD, newWorkflowStatusCode)) {
87              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
88          } else if (KEWConstants.ROUTE_HEADER_CANCEL_CD .equals(newWorkflowStatusCode)) {
89              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_NOT_APPROVED);
90          } else if (KEWConstants.ROUTE_HEADER_ENROUTE_CD.equals(newWorkflowStatusCode)) {
91              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
92          } else if (KEWConstants.ROUTE_HEADER_DISAPPROVED_CD.equals(newWorkflowStatusCode)) {
93              
94  
95  
96              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_NOT_APPROVED);
97          } else if (KEWConstants.ROUTE_HEADER_PROCESSED_CD.equals(newWorkflowStatusCode)) {
98              return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_ACTIVE);
99          } else if (KEWConstants.ROUTE_HEADER_EXCEPTION_CD.equals(newWorkflowStatusCode)) {
100             return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
101         } else {
102             
103             return null;
104         }
105     }
106 
107     
108 
109 
110 
111     protected String getCourseStateFromNewState(String currentCourseState, String newCourseState) {
112         if (LOG.isInfoEnabled()) {
113             LOG.info("current CLU state is '" + currentCourseState + "' and new CLU state will be '" + newCourseState + "'");
114         }
115         return getStateFromNewState(currentCourseState, newCourseState);
116     }
117 
118     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
119     protected void updateCourse(IDocumentEvent iDocumentEvent, String courseState, CourseInfo courseInfo) throws Exception {
120         
121         boolean requiresSave = false;
122         if (courseState != null) {
123             if (LOG.isInfoEnabled()) {
124                 LOG.info("Setting state '" + courseState + "' on CLU with cluId='" + courseInfo.getId() + "'");
125             }
126             courseInfo.setState(courseState);
127             requiresSave = true;
128         }
129         if (LOG.isInfoEnabled()) {
130             LOG.info("Running preProcessCluSave with cluId='" + courseInfo.getId() + "'");
131         }
132         requiresSave |= preProcessCourseSave(iDocumentEvent, courseInfo);
133 
134         if (requiresSave) {
135             getCourseService().updateCourse(courseInfo);
136             
137             
138             if (DtoConstants.STATE_ACTIVE.equals(courseState) && courseInfo.getVersionInfo().getCurrentVersionStart() == null){
139             	
140                 
141             	
142             	
143             		getCourseService().setCurrentCourseVersion(courseInfo.getId(), null);
144             	
145             }
146             
147             List<StatementTreeViewInfo> statementTreeViewInfos = courseService.getCourseStatements(courseInfo.getId(), null, null);
148             if(statementTreeViewInfos!=null){
149 	            statementTreeViewInfoStateSetter(courseInfo.getState(), statementTreeViewInfos.iterator());
150 	            
151 	            for(Iterator<StatementTreeViewInfo> it = statementTreeViewInfos.iterator(); it.hasNext();)
152 	        		courseService.updateCourseStatement(courseInfo.getId(), it.next());
153             }
154         }
155         
156     }
157 
158     protected boolean preProcessCourseSave(IDocumentEvent iDocumentEvent, CourseInfo courseInfo) {
159         return false;
160     }
161 
162     protected CourseService getCourseService() {
163         if (this.courseService == null) {
164             this.courseService = (CourseService) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/course","CourseService")); 
165         }
166         return this.courseService;
167     }
168     protected CourseStateChangeServiceImpl getCourseStateChangeService() {
169         if (this.courseStateChangeService == null) {
170             this.courseStateChangeService = new CourseStateChangeServiceImpl();
171             this.courseStateChangeService.setCourseService(getCourseService());
172         }
173         return this.courseStateChangeService;
174     }    
175     
176 
177 
178    
179     public void statementTreeViewInfoStateSetter(String courseState, Iterator<StatementTreeViewInfo> itr) {
180     	while(itr.hasNext()) {
181         	StatementTreeViewInfo statementTreeViewInfo = (StatementTreeViewInfo)itr.next();
182         	statementTreeViewInfo.setState(courseState);
183         	List<ReqComponentInfo> reqComponents = statementTreeViewInfo.getReqComponents();
184         	for(Iterator<ReqComponentInfo> it = reqComponents.iterator(); it.hasNext();)
185         		it.next().setState(courseState);
186 
187         	statementTreeViewInfoStateSetter(courseState, statementTreeViewInfo.getStatements().iterator());
188         }
189     }
190 }