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 }