Clover Coverage Report - KS LUM 1.2-SNAPSHOT (Aggregated)
Coverage timestamp: Thu Mar 3 2011 05:26:43 EST
../../../../../img/srcFileCovDistChart0.png 55% of files have more coverage
61   173   29   6.1
36   123   0.48   10
10     2.9  
1    
Warning
  • The source file used to generate this report was changed after Clover generated coverage information. The coverage reported may not match the source lines. You should regenerate the coverage information and the report to ensure the files are in sync.
 
  CoursePostProcessorBase       Line # 34 61 0% 29 107 0% 0.0
 
No Tests
 
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.OperationFailedException;
20    import org.kuali.student.core.proposal.dto.ProposalInfo;
21    import org.kuali.student.core.statement.dto.ReqComponentInfo;
22    import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
23    import org.kuali.student.lum.course.dto.CourseInfo;
24    import org.kuali.student.lum.course.service.CourseService;
25    import org.kuali.student.lum.course.service.CourseServiceConstants;
26    import org.springframework.transaction.annotation.Transactional;
27   
28    /**
29    * A base post processor class for Course document types in Workflow.
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   
38    @Override
 
39  0 toggle protected void processWithdrawActionTaken(ActionTakenEvent actionTakenEvent, ProposalInfo proposalInfo) throws Exception {
40    LOG.info("Will set CLU state to '" + DtoConstants.STATE_SUBMITTED + "'");
41  0 CourseInfo courseInfo = getCourseService().getCourse(getCourseId(proposalInfo));
42  0 updateCourse(actionTakenEvent, DtoConstants.STATE_SUBMITTED, courseInfo);
43  0 }
44   
45    @Override
 
46  0 toggle protected boolean processCustomActionTaken(ActionTakenEvent actionTakenEvent, ActionTakenValue actionTaken, ProposalInfo proposalInfo) throws Exception {
47    String cluId = getCourseId(proposalInfo);
48  0 CourseInfo courseInfo = getCourseService().getCourse(cluId);
49  0 updateCourse(actionTakenEvent, null, courseInfo);
50  0 return true;
51  0 }
52   
53    @Override
 
54  0 toggle protected boolean processCustomRouteStatusChange(DocumentRouteStatusChange statusChangeEvent, ProposalInfo proposalInfo) throws Exception {
55    // update the course state if the cluState value is not null (allows for clearing of the state)
56    String courseId = getCourseId(proposalInfo);
57  0 CourseInfo courseInfo = getCourseService().getCourse(courseId);
58  0 String courseState = getCluStateForRouteStatus(courseInfo.getState(), statusChangeEvent.getNewRouteStatus());
59  0 updateCourse(statusChangeEvent, courseState, courseInfo);
60  0 return true;
61  0 }
62   
63    protected String getCourseId(ProposalInfo proposalInfo) throws OperationFailedException {
 
64  0 toggle if (proposalInfo.getProposalReference().size() != 1) {
65  0 LOG.error("Found " + proposalInfo.getProposalReference().size() + " CLU objects linked to proposal with proposalId='" + proposalInfo.getId() + "'. Must have exactly 1 linked.");
66  0 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.");
67  0 }
68    return proposalInfo.getProposalReference().get(0);
69  0 }
70   
71    /**
72    * @param currentCluState - the current state set on the CLU
73    * @param newWorkflowStatusCode - the new route status code that is getting set on the workflow document
74    * @return the CLU state to set or null if the CLU does not need it's state changed
75    */
76    protected String getCluStateForRouteStatus(String currentCluState, String newWorkflowStatusCode) {
 
77  0 toggle if (StringUtils.equals(KEWConstants.ROUTE_HEADER_SAVED_CD, newWorkflowStatusCode)) {
78  0 return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
79  0 } else if (KEWConstants.ROUTE_HEADER_CANCEL_CD .equals(newWorkflowStatusCode)) {
80  0 return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_DRAFT);
81  0 } else if (KEWConstants.ROUTE_HEADER_ENROUTE_CD.equals(newWorkflowStatusCode)) {
82  0 return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_SUBMITTED);
83  0 } else if (KEWConstants.ROUTE_HEADER_DISAPPROVED_CD.equals(newWorkflowStatusCode)) {
84  0 /* current requirements state that on a Withdraw (which is a KEW Disapproval) the
85    * CLU state should be submitted so no special handling required here
86    */
87    return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_SUBMITTED);
88  0 } else if (KEWConstants.ROUTE_HEADER_PROCESSED_CD.equals(newWorkflowStatusCode)) {
89  0 return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_APPROVED);
90  0 } else if (KEWConstants.ROUTE_HEADER_EXCEPTION_CD.equals(newWorkflowStatusCode)) {
91  0 return getCourseStateFromNewState(currentCluState, DtoConstants.STATE_SUBMITTED);
92  0 } else {
93    // no status to set
94    return null;
95  0 }
96    }
97   
98    /**
99    * Default behavior is to return the <code>newCluState</code> variable only if it differs from the
100    * <code>currentCluState</code> value. Otherwise <code>null</code> will be returned.
101    */
102    protected String getCourseStateFromNewState(String currentCourseState, String newCourseState) {
 
103  0 toggle if (LOG.isInfoEnabled()) {
104  0 LOG.info("current CLU state is '" + currentCourseState + "' and new CLU state will be '" + newCourseState + "'");
105  0 }
106    return getStateFromNewState(currentCourseState, newCourseState);
107  0 }
108   
109    @Transactional(readOnly=false)
 
110  0 toggle protected void updateCourse(IDocumentEvent iDocumentEvent, String courseState, CourseInfo courseInfo) throws Exception {
111    // only change the state if the course is not currently set to that state
112    boolean requiresSave = false;
113  0 if (courseState != null) {
114  0 if (LOG.isInfoEnabled()) {
115  0 LOG.info("Setting state '" + courseState + "' on CLU with cluId='" + courseInfo.getId() + "'");
116  0 }
117    courseInfo.setState(courseState);
118  0 requiresSave = true;
119  0 }
120    if (LOG.isInfoEnabled()) {
121  0 LOG.info("Running preProcessCluSave with cluId='" + courseInfo.getId() + "'");
122  0 }
123    requiresSave |= preProcessCourseSave(iDocumentEvent, courseInfo);
124  0
125    if (requiresSave) {
126  0 getCourseService().updateCourse(courseInfo);
127  0
128    //For a newly approved course (w/no prior active versions), make the new course the current version.
129    if (DtoConstants.STATE_APPROVED.equals(courseState) && courseInfo.getVersionInfo().getCurrentVersionStart() == null){
130  0 // TODO: set states of other approved courses to superseded
131   
132    // if current version's state is not active then we can set this course as the active course
133    if (!DtoConstants.STATE_ACTIVE.equals(getCourseService().getCourse(getCourseService().getCurrentVersion(CourseServiceConstants.COURSE_NAMESPACE_URI, courseInfo.getVersionInfo().getVersionIndId()).getId()).getState())) {
134  0 getCourseService().setCurrentCourseVersion(courseInfo.getId(), null);
135  0 }
136    }
137   
138    List<StatementTreeViewInfo> statementTreeViewInfos = courseService.getCourseStatements(courseInfo.getId(), null, null);
139   
140  0 statementTreeViewInfoStateSetter(courseInfo.getState(), statementTreeViewInfos.iterator());
141   
142  0 for(Iterator<StatementTreeViewInfo> it = statementTreeViewInfos.iterator(); it.hasNext();)
143    courseService.updateCourseStatement(courseInfo.getId(), it.next());
144  0 }
145  0
146    }
147   
148    protected boolean preProcessCourseSave(IDocumentEvent iDocumentEvent, CourseInfo courseInfo) {
 
149  0 toggle return false;
150  0 }
151   
152    protected CourseService getCourseService() {
 
153  0 toggle if (this.courseService == null) {
154  0 this.courseService = (CourseService) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/course","CourseService"));
155  0 }
156    return this.courseService;
157  0 }
158   
159    /*
 
160  0 toggle * Recursively set state for StatementTreeViewInfo
161  0 * TODO: We are not able to reuse the code in CourseStateUtil for dependency reason.
162  0 */
163  0 public void statementTreeViewInfoStateSetter(String courseState, Iterator<StatementTreeViewInfo> itr) {
164  0 while(itr.hasNext()) {
165  0 StatementTreeViewInfo statementTreeViewInfo = (StatementTreeViewInfo)itr.next();
166  0 statementTreeViewInfo.setState(courseState);
167    List<ReqComponentInfo> reqComponents = statementTreeViewInfo.getReqComponents();
168  0 for(Iterator<ReqComponentInfo> it = reqComponents.iterator(); it.hasNext();)
169    it.next().setState(courseState);
170   
171    statementTreeViewInfoStateSetter(courseState, statementTreeViewInfo.getStatements().iterator());
172    }
173    }
174   
175   
176    }