1 package org.kuali.student.enrollment.class2.courseofferingset.service.impl;
2
3 import org.apache.commons.lang.ArrayUtils;
4 import org.apache.commons.lang.StringUtils;
5 import org.apache.log4j.Logger;
6 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
7 import org.kuali.student.enrollment.courseoffering.dto.ActivityOfferingInfo;
8 import org.kuali.student.enrollment.courseoffering.service.CourseOfferingService;
9 import org.kuali.student.enrollment.courseofferingset.dto.SocInfo;
10 import org.kuali.student.enrollment.courseofferingset.service.CourseOfferingSetService;
11 import org.kuali.student.r2.common.dto.ContextInfo;
12 import org.kuali.student.r2.common.dto.StatusInfo;
13 import org.kuali.student.r2.common.exceptions.*;
14 import org.kuali.student.r2.common.util.constants.CourseOfferingServiceConstants;
15 import org.kuali.student.r2.common.util.constants.CourseOfferingSetServiceConstants;
16 import org.kuali.student.r2.common.util.constants.LuiServiceConstants;
17
18 import javax.xml.namespace.QName;
19 import java.util.Date;
20 import java.util.List;
21
22
23
24
25
26
27
28 public class CourseOfferingSetPublishingHelper {
29 final static Logger LOG = Logger.getLogger(CourseOfferingSetPublishingHelper.class);
30
31 private CourseOfferingService coService;
32 private CourseOfferingSetService socService;
33
34
35
36
37
38
39
40
41
42 public StatusInfo startMassPublishingEvent(String socId, List<String> optionKeys, ContextInfo context)
43 throws InvalidParameterException, MissingParameterException, DoesNotExistException, PermissionDeniedException, OperationFailedException {
44
45
46 SocInfo soc = getSocService().getSoc(socId, context);
47 if ( ! StringUtils.equals(soc.getStateKey(), CourseOfferingSetServiceConstants.PUBLISHING_SOC_STATE_KEY)) {
48 throw new OperationFailedException(String.format("SOC state [%s] was invalid for mass publishing.", soc.getStateKey()));
49 }
50
51 if (! StringUtils.equals(soc.getSchedulingStateKey(), CourseOfferingSetServiceConstants.SOC_SCHEDULING_STATE_COMPLETED)) {
52 throw new OperationFailedException(String.format("SOC scheduling state [%s] was invalid for mass publishing.", soc.getStateKey()));
53 }
54
55
56 final SocMassPublishingRunner runner = new SocMassPublishingRunner();
57 runner.setCoService(getCourseOfferingService());
58 runner.setSocService(getSocService());
59 runner.setSocId(socId);
60 runner.setContext(context);
61
62 if (optionKeys.contains(CourseOfferingSetServiceConstants.RUN_SYNCHRONOUSLY_OPTION_KEY)) {
63
64 runner.run();
65 } else {
66
67 KSThreadRunnerAfterTransactionSynchronization.runAfterTransactionCompletes(runner);
68 }
69
70 StatusInfo statusInfo = new StatusInfo();
71 statusInfo.setSuccess(true);
72 statusInfo.setMessage("Success");
73
74 return statusInfo;
75 }
76
77
78 public void setCoService(CourseOfferingService coService) {
79 this.coService = coService;
80 }
81
82 public void setSocService(CourseOfferingSetService socService) {
83 this.socService = socService;
84 }
85
86 private CourseOfferingSetService getSocService() {
87 if (socService == null) {
88 socService = (CourseOfferingSetService) GlobalResourceLoader.getService(new QName(CourseOfferingSetServiceConstants.NAMESPACE,
89 CourseOfferingSetServiceConstants.SERVICE_NAME_LOCAL_PART));
90 }
91 return socService;
92 }
93
94 private CourseOfferingService getCourseOfferingService() {
95 if (coService == null) {
96 coService = (CourseOfferingService) GlobalResourceLoader.getService(new QName(CourseOfferingServiceConstants.NAMESPACE,
97 CourseOfferingServiceConstants.SERVICE_NAME_LOCAL_PART));
98 }
99 return coService;
100 }
101
102
103
104
105
106
107 public class SocMassPublishingRunner implements Runnable {
108 private ContextInfo context;
109 private CourseOfferingService coService;
110 private CourseOfferingSetService socService;
111
112 private String socId;
113
114 private final String[] aoSchedStatesForOfferedKeys = {
115 LuiServiceConstants.LUI_AO_SCHEDULING_STATE_EXEMPT_KEY,
116 LuiServiceConstants.LUI_AO_SCHEDULING_STATE_SCHEDULED_KEY
117 };
118 private final String aoOfferedKey = LuiServiceConstants.LUI_AO_STATE_OFFERED_KEY;
119 private final String aoApprovedKey = LuiServiceConstants.LUI_AO_STATE_APPROVED_KEY;
120 private final String foOfferedKey = LuiServiceConstants.LUI_FO_STATE_OFFERED_KEY;
121
122 @Override
123 public void run() {
124 boolean success = true;
125 try {
126 doMpe();
127 } catch(Exception e) {
128 LOG.error("The Mass Publishing Event did not complete successfully.", e);
129 success = false;
130 }
131
132 if (! success) {
133 LOG.warn(String.format("Changing SOC state back to [%s].", CourseOfferingSetServiceConstants.FINALEDITS_SOC_STATE_KEY));
134 StatusInfo statusInfo = null;
135 try {
136 statusInfo = socService.updateSocState(socId, CourseOfferingSetServiceConstants.FINALEDITS_SOC_STATE_KEY, context);
137 } catch (Exception e) {
138 LOG.error(String.format("Unable to change SOC state back to [%s]. The SOC state will have to be manually updated to recover.",
139 CourseOfferingSetServiceConstants.FINALEDITS_SOC_STATE_KEY));
140 }
141 if (statusInfo == null || ! statusInfo.getIsSuccess()) {
142 throw new RuntimeException(String.format("State changed failed for SOC [%s]: %s", socId, statusInfo.getMessage()));
143 }
144 }
145 }
146
147 private void doMpe() throws Exception {
148 LOG.warn(String.format("Beginning Mass Publishing Event for SOC [%s].", socId));
149 context.setCurrentDate(new Date());
150
151
152
153 List<String> coIds = socService.getCourseOfferingIdsBySoc(socId, context);
154 for (String coId : coIds) {
155 boolean hasAOStateChange = false;
156 List<ActivityOfferingInfo> activityOfferings = coService.getActivityOfferingsByCourseOffering(coId, context);
157 for (ActivityOfferingInfo ao : activityOfferings) {
158
159
160
161
162 String aoState = ao.getStateKey();
163 String aoSchedState = ao.getSchedulingStateKey();
164 if (LOG.isDebugEnabled()) {
165 LOG.debug(String.format("Inspecting CO [%s] AO [%s] in state %s and scheduling state [%s].", coId, ao.getId(), aoState, aoSchedState));
166 }
167 if (StringUtils.equals(aoState, aoApprovedKey) && ArrayUtils.contains(aoSchedStatesForOfferedKeys, aoSchedState)) {
168 if (! hasAOStateChange) {
169 hasAOStateChange = true;
170 }
171 StatusInfo statusInfo = coService.updateActivityOfferingState(ao.getId(), aoOfferedKey, context);
172 if ( ! statusInfo.getIsSuccess()) {
173 LOG.error(String.format("State change failed for AO [%s]: %s", ao.getId(), statusInfo.getMessage()));
174 } else {
175 if (LOG.isDebugEnabled()) {
176 LOG.debug(String.format("Updating AO [%s] state to [%s].", ao.getId(), aoState));
177 }
178 }
179
180 statusInfo = coService.updateFormatOfferingState(ao.getFormatOfferingId(), foOfferedKey, context);
181 if ( ! statusInfo.getIsSuccess()) {
182 LOG.error(String.format("State change failed for FO [%s]: %s", ao.getFormatOfferingId(), statusInfo.getMessage()));
183 } else {
184 if (LOG.isDebugEnabled()) {
185 LOG.debug(String.format("Updating FO [%s] state to [%s].", ao.getFormatOfferingId(), foOfferedKey));
186 }
187 }
188 } else {
189 if (LOG.isDebugEnabled()) {
190 LOG.debug(String.format("CO [%s] AO [%s] doesn't need a state change.", coId, ao.getId()));
191 }
192 }
193 }
194
195
196 if (hasAOStateChange) {
197 coService.updateCourseOfferingState(coId, LuiServiceConstants.LUI_CO_STATE_OFFERED_KEY, context);
198 if (LOG.isDebugEnabled()) {
199 LOG.debug(String.format("Updating CO [%s] state to [%s].", coId, LuiServiceConstants.LUI_CO_STATE_OFFERED_KEY));
200 }
201 }
202 }
203
204
205 LOG.warn(String.format("Updating SOC [%s] state to [%s].", socId, CourseOfferingSetServiceConstants.PUBLISHED_SOC_STATE_KEY));
206 context.setCurrentDate(new Date());
207 StatusInfo statusInfo = socService.updateSocState(socId, CourseOfferingSetServiceConstants.PUBLISHED_SOC_STATE_KEY, context);
208 if ( ! statusInfo.getIsSuccess()) {
209 throw new RuntimeException(String.format("State changed failed for SOC [%s]: %s", socId, statusInfo.getMessage()));
210 }
211
212 LOG.warn(String.format("Mass Publishing Event for SOC [%s] completed.", socId));
213 }
214
215 public String getSocId() {
216 return socId;
217 }
218
219 public void setSocId(String socId) {
220 this.socId = socId;
221 }
222
223 public void setContext(ContextInfo context) {
224 this.context = context;
225 }
226
227 public void setCoService(CourseOfferingService coService) {
228 this.coService = coService;
229 }
230
231 public void setSocService(CourseOfferingSetService socService) {
232 this.socService = socService;
233 }
234 }
235 }