Clover Coverage Report - Kuali Student 1.2-M3-SNAPSHOT (Aggregated)
Coverage timestamp: Mon Jun 6 2011 05:02:46 EDT
../../../../../../img/srcFileCovDistChart0.png 52% of files have more coverage
37   233   13   4.62
10   79   0.35   8
8     1.62  
1    
 
  ProgramStateChangeServiceImpl       Line # 30 37 0% 13 55 0% 0.0
 
No Tests
 
1    package org.kuali.student.lum.program.server;
2   
3    import java.util.List;
4   
5    import org.kuali.student.common.dto.DtoConstants;
6    import org.kuali.student.common.exceptions.DoesNotExistException;
7    import org.kuali.student.common.exceptions.InvalidParameterException;
8    import org.kuali.student.common.versionmanagement.dto.VersionDisplayInfo;
9    import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
10    import org.kuali.student.lum.common.server.StatementUtil;
11    import org.kuali.student.lum.course.dto.LoDisplayInfo;
12    import org.kuali.student.lum.program.dto.MajorDisciplineInfo;
13    import org.kuali.student.lum.program.dto.ProgramRequirementInfo;
14    import org.kuali.student.lum.program.dto.ProgramVariationInfo;
15    import org.kuali.student.lum.program.service.ProgramService;
16    import org.kuali.student.lum.program.service.ProgramServiceConstants;
17    import org.springframework.transaction.annotation.Transactional;
18   
19    /**
20    * This class is called whenever the state of a major discipline changes.
21    * <p>
22    * We have a separate class because the operations need to be marked with the @Transactional annotation.
23    * <p>
24    * THIS CLASS IS DUPLICATED FOR MAJOR DISCIPLINE, CORE, AND CREDENTIAL PROGRAMS SINCE THERE ARE DIFFERENT
25    * SERVICE METHODS FOR EACH OF THESE TYPES (THOUGH THEY ARE SIMILAR)
26    * <P>
27    * @author Kuali Rice Team (kuali-rice@googlegroups.com)
28    */
29    @Transactional(noRollbackFor = {DoesNotExistException.class}, rollbackFor = {Throwable.class})
 
30    public class ProgramStateChangeServiceImpl {
31   
32    /**
33    * The program service - injected by spring.
34    */
35    private ProgramService programService;
36   
37   
38   
39    /**
40    * This method is called by workflow when the state changes.
41    *
42    * @param majorDisciplineId
43    * @param state
44    * @return
45    * @throws Exception
46    */
 
47  0 toggle public void changeState( String majorDisciplineId, String newState) throws Exception {
48    // This method will be called from workflow.
49    // Since we cannot activate a program from the workflow we do not need to add endEntryTerm and endEnrollTerm
50  0 changeState(null, null, majorDisciplineId, newState);
51    }
52   
53    /**
54    * This method is called from the UI (servlet) when state changes.
55    *
56    * @param endEntryTerm
57    * @param endEnrollTerm
58    * @param programType
59    * @param majorDisciplineId
60    * @param newState
61    * @return
62    * @throws Exception
63    */
 
64  0 toggle public void changeState(String endEntryTerm, String endEnrollTerm, String majorDisciplineId, String newState) throws Exception {
65   
66    // New state must not be null
67  0 if (newState == null)
68  0 throw new InvalidParameterException("new state cannot be null");
69   
70    // The version selected in the UI
71  0 MajorDisciplineInfo selectedVersion = programService.getMajorDiscipline(majorDisciplineId);
72   
73    // If we are activating this version we need to mark the previous version superseded,
74    // update the previous version end terms, and make the selected version current.
75  0 if (newState.equals(DtoConstants.STATE_ACTIVE)) {
76   
77    // Find the previous version
78  0 MajorDisciplineInfo previousVersion = findPreviousVersion(selectedVersion);
79   
80  0 if (previousVersion != null) {
81   
82    // Set end terms on previous version
83  0 setEndTerms(previousVersion, endEntryTerm, endEnrollTerm);
84   
85    // Mark previous version as superseded and update state on all associated objects
86  0 updateMajorDisciplineInfoState(previousVersion, DtoConstants.STATE_SUPERSEDED);
87    }
88   
89    // Update state of all associated objects for current version
90    // NOTE: we must update state BEFORE making the version current
91  0 updateMajorDisciplineInfoState(selectedVersion, newState);
92   
93    // Make this the current version
94  0 makeCurrent(selectedVersion);
95    } else {
96   
97    // Update state of all associated objects for current version
98  0 updateMajorDisciplineInfoState(selectedVersion, newState);
99    }
100   
101   
102    }
103   
104    /**
105    * This method updates the end terms for the major discipline passed into it.
106    * <p>
107    * You must still call updateState() to save the object using the web service.
108    *
109    * @param majorDisciplineInfo
110    * @param endEntryTerm
111    * @param endEnrollTerm
112    */
 
113  0 toggle private void setEndTerms(MajorDisciplineInfo majorDisciplineInfo, String endEntryTerm, String endEnrollTerm) {
114  0 majorDisciplineInfo.setEndProgramEntryTerm(endEntryTerm);
115  0 majorDisciplineInfo.setEndTerm(endEnrollTerm);
116    }
117   
118    /**
119    * This method will update the state of this object and all associated objects.
120    * <p>
121    * It is needed because we need to make separate web service calls to update the state of these objects.
122    *
123    * @param majorDisciplineInfo
124    * @param newState
125    */
 
126  0 toggle private void updateMajorDisciplineInfoState(MajorDisciplineInfo majorDisciplineInfo, String newState) throws Exception {
127    // Update the statement tree
128  0 updateRequirementsState(majorDisciplineInfo, newState);
129   
130    // Update major discipline
131  0 majorDisciplineInfo.setState(newState);
132  0 programService.updateMajorDiscipline(majorDisciplineInfo);
133    }
134   
135    /**
136    * This method will make this version of the major discipline the current one.
137    *
138    * @param majorDisciplineInfo
139    */
 
140  0 toggle private void makeCurrent(MajorDisciplineInfo majorDisciplineInfo) throws Exception {
141   
142    // Check if this is the current version before trying to make it current
143    // (the web service will error if you try to make a version current that is already current)
144  0 VersionDisplayInfo currentVersion = programService.getCurrentVersion(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI, majorDisciplineInfo.getVersionInfo().getVersionIndId());
145   
146    // If this is not the current version, then make it current
147  0 if (!currentVersion.getSequenceNumber().equals(majorDisciplineInfo.getVersionInfo().getSequenceNumber())) {
148  0 programService.setCurrentMajorDisciplineVersion(majorDisciplineInfo.getId(), null);
149    }
150    }
151   
152    /**
153    * This method finds the previous version (the version right before this one).
154    * <p>
155    * e.g. v1 = ACTIVE v2 = APPROVED
156    * <p>
157    * If you passed v2 into this method, it would return v1.
158    * <p>
159    * If there is only one major discipline this method will return null.
160    *
161    * @param majorDisciplineInfo
162    * @return
163    */
 
164  0 toggle private MajorDisciplineInfo findPreviousVersion(MajorDisciplineInfo majorDisciplineInfo) throws Exception {
165    // Find all previous versions using the version independent indicator
166  0 List<VersionDisplayInfo> versions = programService.getVersions(ProgramServiceConstants.PROGRAM_NAMESPACE_MAJOR_DISCIPLINE_URI, majorDisciplineInfo.getVersionInfo().getVersionIndId());
167   
168    // Take the sequence number for this version
169  0 Long sequenceNumber = majorDisciplineInfo.getVersionInfo().getSequenceNumber();
170   
171    // And subtract 1 from the sequence number to get the previous version
172  0 sequenceNumber -= 1;
173   
174    // Loop over all versions and find the previous version based on the sequence number
175    /*
176    * NOTE: Dan suggested we loop over all versions and change any version with state=active to
177    * state=superseded. However, we decided not to go that route because we would need
178    * to pull back all data for each version to determine if a version is active, since
179    * versioninfo does not have a getState() method
180    */
181  0 MajorDisciplineInfo previousVersion = null;
182  0 for (VersionDisplayInfo versionInfo : versions) {
183  0 if (versionInfo.getSequenceNumber().equals(sequenceNumber)) {
184  0 previousVersion = programService.getMajorDiscipline(versionInfo.getId());
185  0 break;
186    }
187    }
188  0 return previousVersion;
189    }
190   
191    /**
192    * This method will update the requirement state.
193    * <p>
194    * Note that it uses StatementUtil to update the statement tree.
195    *
196    * @param majorDisciplineInfo
197    * @param newState
198    * @throws Exception
199    */
 
200  0 toggle public void updateRequirementsState(MajorDisciplineInfo majorDisciplineInfo, String newState) throws Exception {
201   
202    // Loop over list of requirement ids returned in the major discipline object
203  0 List<String> programRequirementIds = majorDisciplineInfo.getProgramRequirements();
204  0 for (String programRequirementId : programRequirementIds) {
205   
206    // Get program requirement from the program service
207  0 ProgramRequirementInfo programRequirementInfo = programService.getProgramRequirement(programRequirementId, null, null);
208   
209    // Look in the requirement for the statement tree
210  0 StatementTreeViewInfo statementTree = programRequirementInfo.getStatement();
211   
212    // And recursively update the entire tree with the new state
213  0 StatementUtil.updateStatementTreeViewInfoState(newState, statementTree);
214   
215    // Update the state of the requirement object
216  0 programRequirementInfo.setState(newState);
217   
218    // The write the requirement back to the program service
219  0 programService.updateProgramRequirement(programRequirementInfo);
220   
221    }
222    }
223   
224    /**
225    * This method is used by Spring to inject the program service into this bean.
226    *
227    * @param programService
228    */
 
229  0 toggle public void setProgramService(ProgramService programService) {
230  0 this.programService = programService;
231    }
232   
233    }