1 | |
package org.kuali.student.enrollment.acal; |
2 | |
|
3 | |
|
4 | |
import java.io.BufferedReader; |
5 | |
import java.io.BufferedWriter; |
6 | |
import java.io.DataInputStream; |
7 | |
import java.io.File; |
8 | |
import java.io.FileInputStream; |
9 | |
import java.io.FileWriter; |
10 | |
import java.io.IOException; |
11 | |
import java.io.InputStreamReader; |
12 | |
import java.text.SimpleDateFormat; |
13 | |
import java.util.ArrayList; |
14 | |
import java.util.Arrays; |
15 | |
import java.util.Calendar; |
16 | |
import java.util.Date; |
17 | |
import java.util.GregorianCalendar; |
18 | |
import java.util.HashMap; |
19 | |
import java.util.HashSet; |
20 | |
import java.util.LinkedHashMap; |
21 | |
import java.util.List; |
22 | |
import java.util.Map; |
23 | |
import java.util.Set; |
24 | |
|
25 | 0 | public class AcalReferenceDataParser { |
26 | 0 | private List<Map<String, String>> dataSet = new ArrayList<Map<String, String>>(); |
27 | 0 | private Map<String, Atp> allAcals = new LinkedHashMap<String, Atp>(); |
28 | 0 | private Map<String, Atp> allHolidayCalendars = new LinkedHashMap<String, Atp>(); |
29 | |
|
30 | |
private static final String FALL_ATP_TYPE = "Fall"; |
31 | |
private static final String WINTER_ATP_TYPE = "Winter"; |
32 | |
private static final String SPRING_ATP_TYPE = "Spring"; |
33 | |
private static final String SUMMER_ATP_TYPE = "Summer"; |
34 | |
private static final String SESSION1_ATP_TYPE = "Session 1"; |
35 | |
private static final String SESSION2_ATP_TYPE = "Session 2"; |
36 | |
private static final String FALL_ATP_TYPE_KEY = "kuali.atp.type.Fall"; |
37 | |
private static final String WINTER_ATP_TYPE_KEY = "kuali.atp.type.Winter"; |
38 | |
private static final String SPRING_ATP_TYPE_KEY = "kuali.atp.type.Spring"; |
39 | |
private static final String SUMMER_ATP_TYPE_KEY = "kuali.atp.type.Summer"; |
40 | |
private static final String SESSION1_ATP_TYPE_KEY = "kuali.atp.type.Session1"; |
41 | |
private static final String SESSION2_ATP_TYPE_KEY = "kuali.atp.type.Session2"; |
42 | |
|
43 | |
private static final String RECORD_KEY = "table_key"; |
44 | |
|
45 | |
private static final String RECORD_FIRST_DAY = "first_day"; |
46 | |
private static final String RECORD_CENSUS_DAY = "tenth_day"; |
47 | |
private static final String RECORD_LAST_DAY_ADD = "last_day_add"; |
48 | |
private static final String RECORD_LAST_DAY_DROP_NOT = "last_drop_not"; |
49 | |
private static final String RECORD_DROP_UG = "last_drop_ug"; |
50 | |
private static final String RECORD_DROP_GRAD = "last_drop_grad"; |
51 | |
private static final String RECORD_LAST_DAY_CLASSES = "last_day_classes"; |
52 | |
private static final String RECORD_LAST_DAY_EXAMS = "last_day_exams"; |
53 | |
private static final String RECORD_GRADE_SUBMIT_DEADLINE_DATE = "grade_submit_ddln"; |
54 | |
private static final String RECORD_GRADE_SUBMIT_DEADLINE_TIME = "grade_submit_ddtm"; |
55 | |
|
56 | |
private static final String RECORD_SUB_1_FIRST_DAY = "first_day"; |
57 | |
private static final String RECORD_SUB_1_CENSUS_DAY = "tenth_day"; |
58 | |
private static final String RECORD_SUB_1_LAST_DAY_ADD = "last_day_add_a"; |
59 | |
private static final String RECORD_SUB_1_LAST_DAY_DROP_NOT = "last_drop_not_a"; |
60 | |
private static final String RECORD_SUB_1_DROP_UG = "last_a_drop_ug"; |
61 | |
private static final String RECORD_SUB_1_DROP_GRAD = "last_a_drop_grad"; |
62 | |
private static final String RECORD_SUB_1_LAST_DAY_CLASSES = "last_day_class_a"; |
63 | |
private static final String RECORD_SUB_1_GRADE_SUBMIT_DEADLINE_DATE = "grade_submit_ddln"; |
64 | |
private static final String RECORD_SUB_1_GRADE_SUBMIT_DEADLINE_TIME = "grade_submit_ddtm"; |
65 | |
|
66 | |
private static final String RECORD_SUB_2_FIRST_DAY = "first_day_b"; |
67 | |
private static final String RECORD_SUB_2_LAST_DAY_ADD = "last_day_add_b"; |
68 | |
private static final String RECORD_SUB_2_LAST_DAY_DROP_NOT = "last_drop_not_b"; |
69 | |
private static final String RECORD_SUB_2_DROP_UG = "last_b_drop_ug"; |
70 | |
private static final String RECORD_SUB_2_DROP_GRAD = "last_b_drop_grad"; |
71 | |
private static final String RECORD_SUB_2_LAST_DAY_CLASSES = "last_day_classes"; |
72 | |
private static final String RECORD_SUB_2_LAST_DAY_EXAMS = "last_day_exams"; |
73 | |
private static final String RECORD_SUB_2_GRADE_SUBMIT_DEADLINE_DATE = "grade_submit_ddln"; |
74 | |
private static final String RECORD_SUB_2_GRADE_SUBMIT_DEADLINE_TIME = "grade_submit_ddtm"; |
75 | |
|
76 | |
|
77 | |
private static final String KEYDATE_INSTRUCTIONAL_PERIOD_KEY = "kuali.atp.milestone.InstructionalPeriod"; |
78 | |
private static final String KEYDATE_FINAL_EXAM_PERIOD_KEY = "kuali.atp.milestone.FinalExamPeriod"; |
79 | |
private static final String KEYDATE_CENSUS_KEY = "kuali.atp.milestone.FinancialAidCensus"; |
80 | |
private static final String KEYDATE_DROP_DEADLINE_WITHOUT_RECORD_KEY = "kuali.atp.milestone.DropDeadlineWithoutRecord"; |
81 | |
private static final String KEYDATE_DROP_DEADLINE_KEY = "kuali.atp.milestone.DropDate"; |
82 | |
private static final String KEYDATE_GRADES_DUE_KEY = "kuali.atp.milestone.GradesDue"; |
83 | |
private static final String KEYDATE_COURSE_SELECTION_PERIOD_END_KEY = "kuali.atp.milestone.CourseSelectionPeriodEnd"; |
84 | |
|
85 | 0 | private static final Map<String, String> keydateNames = new LinkedHashMap<String, String>(); |
86 | |
{ |
87 | 0 | keydateNames.put(KEYDATE_INSTRUCTIONAL_PERIOD_KEY, "Instructional Period"); |
88 | 0 | keydateNames.put(KEYDATE_COURSE_SELECTION_PERIOD_END_KEY, "Course Selection Period End"); |
89 | 0 | keydateNames.put(KEYDATE_CENSUS_KEY, "Census"); |
90 | 0 | keydateNames.put(KEYDATE_DROP_DEADLINE_WITHOUT_RECORD_KEY, "Drop Deadline Without Record"); |
91 | 0 | keydateNames.put(KEYDATE_DROP_DEADLINE_KEY, "Drop Deadline"); |
92 | 0 | keydateNames.put(KEYDATE_FINAL_EXAM_PERIOD_KEY, "Final Exam Period"); |
93 | 0 | keydateNames.put(KEYDATE_GRADES_DUE_KEY, "Grades Due"); |
94 | |
} |
95 | |
|
96 | 0 | private static final Set<String> relativeToInstructionPeriod = new HashSet<String>(); |
97 | |
{ |
98 | 0 | relativeToInstructionPeriod.add(KEYDATE_CENSUS_KEY); |
99 | 0 | relativeToInstructionPeriod.add(KEYDATE_COURSE_SELECTION_PERIOD_END_KEY); |
100 | 0 | relativeToInstructionPeriod.add(KEYDATE_FINAL_EXAM_PERIOD_KEY); |
101 | |
} |
102 | |
|
103 | |
private static final String HOLIDAY_NEWYEARSDAY_KEY = "kuali.atp.milestone.NewYearsDay"; |
104 | |
private static final String HOLIDAY_MLKDAY_KEY = "kuali.atp.milestone.MLKDay"; |
105 | |
private static final String HOLIDAY_PRESIDENTSDAY_KEY = "kuali.atp.milestone.PresidentsDay"; |
106 | |
private static final String HOLIDAY_MEMORIALDAY_KEY = "kuali.atp.milestone.MemorialDay"; |
107 | |
private static final String HOLIDAY_INDEPENDENCEDAY_KEY = "kuali.atp.milestone.IndependenceDay"; |
108 | |
private static final String HOLIDAY_LABORDAY_KEY = "kuali.atp.milestone.LaborDay"; |
109 | |
private static final String HOLIDAY_VETERANSDAY_KEY = "kuali.atp.milestone.VeteransDay"; |
110 | |
private static final String HOLIDAY_THANKSGIVINGBREAK_KEY = "kuali.atp.milestone.ThanksgivingBreak"; |
111 | |
private static final String HOLIDAY_CHRISTMAS_KEY = "kuali.atp.milestone.Christmas"; |
112 | |
private static final String HOLIDAY_OTHERNONINSTRUCTIONALHOLIDAY_KEY = "kuali.atp.milestone.OtherNonInstructionalHoliday"; |
113 | |
private static final String HOLIDAY_OTHERNONINSTRUCTIONALDAY_KEY = "kuali.atp.milestone.OtherNonInstructionalDay"; |
114 | |
|
115 | |
private static final String HOLIDAY_NEWYEARSDAYOBSERVED_KEY = "kuali.atp.milestone.NewYearsDayObserved"; |
116 | |
private static final String HOLIDAY_INDEPENDENCEDAYOBSERVED_KEY = "kuali.atp.milestone.IndependenceDayObserved"; |
117 | |
private static final String HOLIDAY_VETERANSDAYOBSERVED_KEY = "kuali.atp.milestone.VeteransDayObserved"; |
118 | |
private static final String HOLIDAY_CHRISTMASOBSERVED_KEY = "kuali.atp.milestone.ChristmasObserved"; |
119 | |
|
120 | |
|
121 | 0 | private static final Map<String, String> holidayNames = new LinkedHashMap<String, String>(); |
122 | |
{ |
123 | 0 | holidayNames.put(HOLIDAY_NEWYEARSDAY_KEY, "New Years Day"); |
124 | 0 | holidayNames.put(HOLIDAY_MLKDAY_KEY, "Martin Luther King, Jr. Day"); |
125 | 0 | holidayNames.put(HOLIDAY_PRESIDENTSDAY_KEY, "Presidents Day"); |
126 | 0 | holidayNames.put(HOLIDAY_MEMORIALDAY_KEY, "Memorial Day"); |
127 | 0 | holidayNames.put(HOLIDAY_INDEPENDENCEDAY_KEY, "Independence Day"); |
128 | 0 | holidayNames.put(HOLIDAY_LABORDAY_KEY, "Labor Day"); |
129 | 0 | holidayNames.put(HOLIDAY_VETERANSDAY_KEY, "Veterans Day"); |
130 | 0 | holidayNames.put(HOLIDAY_THANKSGIVINGBREAK_KEY, "Thanksgiving Break"); |
131 | 0 | holidayNames.put(HOLIDAY_CHRISTMAS_KEY, "Christmas Day"); |
132 | 0 | holidayNames.put(HOLIDAY_NEWYEARSDAYOBSERVED_KEY, "New Years Day Observed"); |
133 | 0 | holidayNames.put(HOLIDAY_INDEPENDENCEDAYOBSERVED_KEY, "Independence Day Observed"); |
134 | 0 | holidayNames.put(HOLIDAY_VETERANSDAYOBSERVED_KEY, "Veterans Day Observed"); |
135 | 0 | holidayNames.put(HOLIDAY_CHRISTMASOBSERVED_KEY, "Christmas Day Observed"); |
136 | |
} |
137 | |
|
138 | |
|
139 | 0 | private static final Map<String, String> observedHolidays = new LinkedHashMap<String, String>(); |
140 | |
{ |
141 | 0 | observedHolidays.put(HOLIDAY_NEWYEARSDAY_KEY, HOLIDAY_NEWYEARSDAYOBSERVED_KEY); |
142 | 0 | observedHolidays.put(HOLIDAY_MLKDAY_KEY, null); |
143 | 0 | observedHolidays.put(HOLIDAY_PRESIDENTSDAY_KEY, null); |
144 | 0 | observedHolidays.put(HOLIDAY_MEMORIALDAY_KEY, null); |
145 | 0 | observedHolidays.put(HOLIDAY_INDEPENDENCEDAY_KEY, HOLIDAY_INDEPENDENCEDAYOBSERVED_KEY); |
146 | 0 | observedHolidays.put(HOLIDAY_LABORDAY_KEY, null); |
147 | 0 | observedHolidays.put(HOLIDAY_VETERANSDAY_KEY, HOLIDAY_VETERANSDAYOBSERVED_KEY); |
148 | 0 | observedHolidays.put(HOLIDAY_THANKSGIVINGBREAK_KEY, null); |
149 | 0 | observedHolidays.put(HOLIDAY_CHRISTMAS_KEY, HOLIDAY_CHRISTMASOBSERVED_KEY); |
150 | 0 | } |
151 | |
|
152 | |
|
153 | |
public static void main(String[] args) { |
154 | 0 | AcalReferenceDataParser parser = new AcalReferenceDataParser(); |
155 | 0 | File inputFile = new File("/kuali/temp/Reference Insitution Data_ Terms - Data.tsv"); |
156 | 0 | File outputFile = new File("/kuali/temp/output.sql"); |
157 | |
|
158 | 0 | parser.loadDataSet(inputFile); |
159 | |
|
160 | 0 | int[] records = new int[] {35}; |
161 | 0 | for (int record : records) { |
162 | |
|
163 | |
} |
164 | |
|
165 | 0 | parser.parse(); |
166 | 0 | SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy"); |
167 | 0 | for (Atp acal : parser.allAcals.values()) { |
168 | 0 | int startYear = Integer.parseInt(yearFormat.format(acal.getStartDate())); |
169 | 0 | int endYear = Integer.parseInt(yearFormat.format(acal.getEndDate())); |
170 | 0 | for (int year = startYear; year <= endYear; year++) { |
171 | 0 | Atp holiCal = parser.getHolidayCalendar(Integer.toString(year)); |
172 | 0 | acal.getHolidayCalendars().add(holiCal); |
173 | |
} |
174 | 0 | } |
175 | |
|
176 | 0 | parser.alterEndDates(new ArrayList<Atp>(parser.allAcals.values())); |
177 | |
|
178 | |
|
179 | |
|
180 | |
|
181 | 0 | SqlGenerator sqlGenerator = new SqlGenerator(); |
182 | 0 | StringBuilder sql = new StringBuilder(); |
183 | 0 | for (Atp acal : parser.allAcals.values()) { |
184 | 0 | sqlGenerator.getSqlForAcademicCalendar(sql, acal); |
185 | |
} |
186 | 0 | parser.writeToFile(outputFile, sql.toString()); |
187 | |
|
188 | |
|
189 | 0 | } |
190 | |
|
191 | |
private void parse() { |
192 | 0 | int i = 0; |
193 | 0 | for (Map<String, String> record : dataSet) { |
194 | 0 | i++; |
195 | |
|
196 | |
|
197 | 0 | Atp term = createTerm(record); |
198 | |
|
199 | |
|
200 | 0 | Atp acal = getAcalForTermId(record.get(RECORD_KEY)); |
201 | 0 | List<Atp> terms = acal.getTerms(); |
202 | 0 | terms.add(term); |
203 | 0 | } |
204 | 0 | for (Atp acal : allAcals.values()) { |
205 | 0 | List<Atp> terms = acal.getTerms(); |
206 | 0 | Atp firstTerm = terms.get(0); |
207 | 0 | Atp lastTerm = terms.get(terms.size() - 1); |
208 | 0 | acal.setStartDate(firstTerm.getStartDate()); |
209 | 0 | acal.setEndDate(lastTerm.getEndDate()); |
210 | 0 | } |
211 | 0 | } |
212 | |
|
213 | |
private Atp createTerm(Map<String, String> record) { |
214 | 0 | String recordKey = record.get(RECORD_KEY); |
215 | 0 | int year = getYear(recordKey); |
216 | 0 | int quarter = getQuarter(recordKey); |
217 | 0 | String termName = getAtpTypeName(quarter); |
218 | |
|
219 | 0 | Atp term = new Atp(); |
220 | |
|
221 | 0 | term.setId((year + "" + termName).replaceAll(" ", "").toUpperCase()); |
222 | 0 | term.setName(termName + " " + year); |
223 | 0 | term.setDescriptionPlain(termName + " " + year); |
224 | 0 | term.setDescriptionFormatted("<p>" + term.getDescriptionPlain() + "</p>"); |
225 | 0 | term.setStartDate(parseDate(record.get(RECORD_FIRST_DAY))); |
226 | 0 | Date termEnd = parseDate(record.get(RECORD_LAST_DAY_EXAMS)); |
227 | 0 | term.setEndDate(termEnd); |
228 | 0 | term.setType(getAtpTypeKey(quarter)); |
229 | 0 | term.setAtpCode(termName.substring(0,3).toUpperCase() + year); |
230 | |
|
231 | 0 | for (String keydateType : keydateNames.keySet()) { |
232 | 0 | term.addMilestone(getKeydateForTerm(keydateType, record)); |
233 | |
} |
234 | |
|
235 | |
|
236 | 0 | if (3 == quarter) { |
237 | 0 | String subtermName = SESSION1_ATP_TYPE; |
238 | 0 | Atp subterm = new Atp(); |
239 | |
|
240 | 0 | subterm.setId((year + "" + subtermName).replaceAll(" ", "").toUpperCase()); |
241 | 0 | subterm.setName(subtermName + " " + year); |
242 | 0 | subterm.setDescriptionPlain(subtermName + " " + year); |
243 | 0 | subterm.setDescriptionFormatted("<p>" + subterm.getDescriptionPlain() + "</p>"); |
244 | 0 | subterm.setStartDate(parseDate(record.get(RECORD_SUB_1_FIRST_DAY))); |
245 | 0 | Date subTermEnd = parseDate(record.get(RECORD_SUB_1_LAST_DAY_CLASSES)); |
246 | 0 | subterm.setEndDate(subTermEnd); |
247 | 0 | subterm.setType(SESSION1_ATP_TYPE_KEY); |
248 | 0 | subterm.setAtpCode(termName.substring(0, 3).toUpperCase() + "A" + year); |
249 | |
|
250 | 0 | for (String keydateType : keydateNames.keySet()) { |
251 | 0 | subterm.addMilestone(getKeydateForSubterm1(keydateType, record)); |
252 | |
} |
253 | |
|
254 | 0 | term.getTerms().add(subterm); |
255 | |
} |
256 | |
|
257 | |
|
258 | |
|
259 | |
|
260 | 0 | if (3 == quarter) { |
261 | 0 | String subtermName = SESSION2_ATP_TYPE; |
262 | 0 | Atp subterm = new Atp(); |
263 | |
|
264 | 0 | subterm.setId((year + "" + subtermName).replaceAll(" ", "").toUpperCase()); |
265 | 0 | subterm.setName(subtermName + " " + year); |
266 | 0 | subterm.setDescriptionPlain(subtermName + " " + year); |
267 | 0 | subterm.setDescriptionFormatted("<p>" + subterm.getDescriptionPlain() + "</p>"); |
268 | 0 | subterm.setStartDate(parseDate(record.get(RECORD_SUB_2_FIRST_DAY))); |
269 | 0 | Date subTermEnd = parseDate(record.get(RECORD_SUB_2_LAST_DAY_EXAMS)); |
270 | 0 | subterm.setEndDate(subTermEnd); |
271 | 0 | subterm.setType(SESSION2_ATP_TYPE_KEY); |
272 | 0 | subterm.setAtpCode(termName.substring(0, 3).toUpperCase() + "A" + year); |
273 | |
|
274 | 0 | for (String keydateType : keydateNames.keySet()) { |
275 | 0 | subterm.addMilestone(getKeydateForSubterm2(keydateType, record)); |
276 | |
} |
277 | |
|
278 | 0 | term.getTerms().add(subterm); |
279 | |
} |
280 | |
|
281 | 0 | addMilestoneRelations(term); |
282 | 0 | return term; |
283 | |
} |
284 | |
|
285 | |
private Milestone getKeydateForTerm(String keydateType, Map<String, String> record) { |
286 | 0 | String recordKey = record.get(RECORD_KEY); |
287 | 0 | int termYear = getYear(recordKey); |
288 | 0 | String termName = getAtpTypeName(getQuarter(recordKey)); |
289 | 0 | String keydateName = keydateNames.get(keydateType); |
290 | |
|
291 | 0 | String id = (termYear + termName + keydateName).replaceAll(" ", "").toUpperCase(); |
292 | 0 | String name = termName + " " + termYear + " " + keydateName; |
293 | 0 | String descriptionPlain = keydateName + " for " + termName + " " + termYear; |
294 | 0 | String descriptionFormatted = "<p>" + descriptionPlain + "<p>"; |
295 | |
|
296 | 0 | Date start = null; |
297 | 0 | Date end = null; |
298 | |
boolean allDay; |
299 | |
boolean range; |
300 | |
|
301 | 0 | if (KEYDATE_COURSE_SELECTION_PERIOD_END_KEY.equals(keydateType)) { |
302 | 0 | start = parseDate(record.get(RECORD_LAST_DAY_ADD)); |
303 | 0 | if (start == null) { |
304 | |
|
305 | 0 | return null; |
306 | |
} |
307 | 0 | allDay = true; |
308 | 0 | range = false; |
309 | |
|
310 | 0 | } else if (KEYDATE_INSTRUCTIONAL_PERIOD_KEY.equals(keydateType)) { |
311 | 0 | start = parseDate(record.get(RECORD_FIRST_DAY)); |
312 | 0 | if (start == null) { |
313 | 0 | throw new RuntimeException(recordKey); |
314 | |
} |
315 | 0 | end = parseDate(record.get(RECORD_LAST_DAY_CLASSES)); |
316 | 0 | if (end == null) { |
317 | 0 | throw new RuntimeException(recordKey); |
318 | |
} |
319 | 0 | allDay = true; |
320 | 0 | range = true; |
321 | |
|
322 | 0 | } else if (KEYDATE_FINAL_EXAM_PERIOD_KEY.equals(keydateType)) { |
323 | 0 | if (3 == getQuarter(record.get(RECORD_KEY))) { |
324 | 0 | return null; |
325 | |
} |
326 | 0 | start = parseDate(record.get(RECORD_LAST_DAY_CLASSES)); |
327 | 0 | if (start == null) { |
328 | 0 | throw new RuntimeException(recordKey); |
329 | |
} |
330 | 0 | start = addToDate(start, Calendar.DATE, 1); |
331 | 0 | end = parseDate(record.get(RECORD_LAST_DAY_EXAMS)); |
332 | 0 | if (end == null) { |
333 | 0 | throw new RuntimeException(recordKey); |
334 | |
} |
335 | 0 | allDay = true; |
336 | 0 | range = true; |
337 | |
|
338 | 0 | } else if (KEYDATE_CENSUS_KEY.equals(keydateType)) { |
339 | 0 | start = parseDate(record.get(RECORD_CENSUS_DAY)); |
340 | 0 | if (start == null) { |
341 | 0 | throw new RuntimeException(recordKey); |
342 | |
} |
343 | 0 | allDay = true; |
344 | 0 | range = false; |
345 | |
|
346 | 0 | } else if (KEYDATE_DROP_DEADLINE_WITHOUT_RECORD_KEY.equals(keydateType)) { |
347 | 0 | start = parseDate(record.get(RECORD_LAST_DAY_DROP_NOT)); |
348 | 0 | if (start == null) { |
349 | 0 | throw new RuntimeException(recordKey); |
350 | |
} |
351 | 0 | allDay = true; |
352 | 0 | range = false; |
353 | |
|
354 | 0 | } else if (KEYDATE_DROP_DEADLINE_KEY.equals(keydateType)) { |
355 | 0 | start = parseDate(record.get(RECORD_DROP_UG)); |
356 | 0 | if (start == null) { |
357 | 0 | throw new RuntimeException(recordKey); |
358 | |
} |
359 | 0 | allDay = true; |
360 | 0 | range = false; |
361 | |
|
362 | 0 | } else if (KEYDATE_GRADES_DUE_KEY.equals(keydateType)) { |
363 | 0 | start = parseDate(record.get(RECORD_GRADE_SUBMIT_DEADLINE_DATE), record.get(RECORD_GRADE_SUBMIT_DEADLINE_TIME)); |
364 | 0 | if (start == null) { |
365 | 0 | return null; |
366 | |
} |
367 | 0 | allDay = false; |
368 | 0 | range = false; |
369 | |
|
370 | |
} else { |
371 | 0 | throw new RuntimeException(recordKey + " Keydate type not known."); |
372 | |
} |
373 | |
|
374 | 0 | Milestone milestone = new Milestone(id, name, keydateType, descriptionPlain, descriptionFormatted, start, end, allDay, range); |
375 | 0 | return milestone; |
376 | |
} |
377 | |
|
378 | |
private Milestone getKeydateForSubterm1(String keydateType, Map<String, String> record) { |
379 | 0 | String recordKey = record.get(RECORD_KEY); |
380 | 0 | int termYear = getYear(recordKey); |
381 | 0 | String termName = SESSION1_ATP_TYPE; |
382 | 0 | String keydateName = keydateNames.get(keydateType); |
383 | |
|
384 | 0 | String id = (termYear + termName + keydateName).replaceAll(" ", "").toUpperCase(); |
385 | 0 | String name = termName + " " + termYear + " " + keydateName; |
386 | 0 | String descriptionPlain = keydateName + " for " + termName + " " + termYear; |
387 | 0 | String descriptionFormatted = "<p>" + descriptionPlain + "<p>"; |
388 | |
|
389 | 0 | Date start = null; |
390 | 0 | Date end = null; |
391 | |
boolean allDay; |
392 | |
boolean range; |
393 | |
|
394 | 0 | if (KEYDATE_COURSE_SELECTION_PERIOD_END_KEY.equals(keydateType)) { |
395 | 0 | start = parseDate(record.get(RECORD_SUB_1_LAST_DAY_ADD)); |
396 | 0 | if (start == null) { |
397 | |
|
398 | 0 | return null; |
399 | |
} |
400 | 0 | allDay = true; |
401 | 0 | range = false; |
402 | |
|
403 | 0 | } else if (KEYDATE_INSTRUCTIONAL_PERIOD_KEY.equals(keydateType)) { |
404 | 0 | start = parseDate(record.get(RECORD_SUB_1_FIRST_DAY)); |
405 | 0 | if (start == null) { |
406 | 0 | throw new RuntimeException(recordKey); |
407 | |
} |
408 | 0 | end = parseDate(record.get(RECORD_SUB_1_LAST_DAY_CLASSES)); |
409 | 0 | if (end == null) { |
410 | 0 | end = parseDate(record.get(RECORD_SUB_2_FIRST_DAY)); |
411 | 0 | end = addToDate(end, Calendar.DATE, -1); |
412 | 0 | if (end == null) { |
413 | 0 | throw new RuntimeException(record.get(RECORD_KEY)); |
414 | |
} |
415 | |
} |
416 | 0 | allDay = true; |
417 | 0 | range = true; |
418 | |
|
419 | 0 | } else if (KEYDATE_FINAL_EXAM_PERIOD_KEY.equals(keydateType)) { |
420 | 0 | return null; |
421 | |
|
422 | 0 | } else if (KEYDATE_CENSUS_KEY.equals(keydateType)) { |
423 | 0 | start = parseDate(record.get(RECORD_SUB_1_CENSUS_DAY)); |
424 | 0 | if (start == null) { |
425 | 0 | throw new RuntimeException(recordKey); |
426 | |
} |
427 | 0 | allDay = true; |
428 | 0 | range = false; |
429 | |
|
430 | 0 | } else if (KEYDATE_DROP_DEADLINE_WITHOUT_RECORD_KEY.equals(keydateType)) { |
431 | 0 | start = parseDate(record.get(RECORD_SUB_1_LAST_DAY_DROP_NOT)); |
432 | 0 | if (start == null) { |
433 | 0 | throw new RuntimeException(recordKey); |
434 | |
} |
435 | 0 | allDay = true; |
436 | 0 | range = false; |
437 | |
|
438 | 0 | } else if (KEYDATE_DROP_DEADLINE_KEY.equals(keydateType)) { |
439 | 0 | start = parseDate(record.get(RECORD_SUB_1_DROP_UG)); |
440 | 0 | if (start == null) { |
441 | 0 | throw new RuntimeException(recordKey); |
442 | |
} |
443 | 0 | allDay = true; |
444 | 0 | range = false; |
445 | |
|
446 | 0 | } else if (KEYDATE_GRADES_DUE_KEY.equals(keydateType)) { |
447 | 0 | start = parseDate(record.get(RECORD_SUB_1_GRADE_SUBMIT_DEADLINE_DATE), record.get(RECORD_SUB_1_GRADE_SUBMIT_DEADLINE_TIME)); |
448 | 0 | if (start == null) { |
449 | 0 | return null; |
450 | |
} |
451 | 0 | allDay = false; |
452 | 0 | range = false; |
453 | |
|
454 | |
} else { |
455 | 0 | throw new RuntimeException(recordKey + " Keydate type not known."); |
456 | |
} |
457 | |
|
458 | 0 | Milestone milestone = new Milestone(id, name, keydateType, descriptionPlain, descriptionFormatted, start, end, allDay, range); |
459 | 0 | return milestone; |
460 | |
} |
461 | |
|
462 | |
private Milestone getKeydateForSubterm2(String keydateType, Map<String, String> record) { |
463 | 0 | String recordKey = record.get(RECORD_KEY); |
464 | 0 | int termYear = getYear(recordKey); |
465 | 0 | String termName = SESSION2_ATP_TYPE; |
466 | 0 | String keydateName = keydateNames.get(keydateType); |
467 | |
|
468 | 0 | String id = (termYear + termName + keydateName).replaceAll(" ", "").toUpperCase(); |
469 | 0 | String name = termName + " " + termYear + " " + keydateName; |
470 | 0 | String descriptionPlain = keydateName + " for " + termName + " " + termYear; |
471 | 0 | String descriptionFormatted = "<p>" + descriptionPlain + "<p>"; |
472 | |
|
473 | 0 | Date start = null; |
474 | 0 | Date end = null; |
475 | |
boolean allDay; |
476 | |
boolean range; |
477 | |
|
478 | 0 | if (KEYDATE_COURSE_SELECTION_PERIOD_END_KEY.equals(keydateType)) { |
479 | 0 | start = parseDate(record.get(RECORD_SUB_2_LAST_DAY_ADD)); |
480 | 0 | if (start == null) { |
481 | |
|
482 | 0 | return null; |
483 | |
} |
484 | 0 | allDay = true; |
485 | 0 | range = false; |
486 | |
|
487 | 0 | } else if (KEYDATE_INSTRUCTIONAL_PERIOD_KEY.equals(keydateType)) { |
488 | 0 | start = parseDate(record.get(RECORD_SUB_2_FIRST_DAY)); |
489 | 0 | if (start == null) { |
490 | 0 | throw new RuntimeException(recordKey); |
491 | |
} |
492 | 0 | end = parseDate(record.get(RECORD_SUB_2_LAST_DAY_CLASSES)); |
493 | 0 | if (end == null) { |
494 | 0 | throw new RuntimeException(recordKey); |
495 | |
} |
496 | 0 | allDay = true; |
497 | 0 | range = true; |
498 | |
|
499 | 0 | } else if (KEYDATE_FINAL_EXAM_PERIOD_KEY.equals(keydateType)) { |
500 | 0 | return null; |
501 | |
|
502 | 0 | } else if (KEYDATE_CENSUS_KEY.equals(keydateType)) { |
503 | 0 | return null; |
504 | |
|
505 | 0 | } else if (KEYDATE_DROP_DEADLINE_WITHOUT_RECORD_KEY.equals(keydateType)) { |
506 | 0 | start = parseDate(record.get(RECORD_SUB_2_LAST_DAY_DROP_NOT)); |
507 | 0 | if (start == null) { |
508 | 0 | throw new RuntimeException(recordKey); |
509 | |
} |
510 | 0 | allDay = true; |
511 | 0 | range = false; |
512 | |
|
513 | 0 | } else if (KEYDATE_DROP_DEADLINE_KEY.equals(keydateType)) { |
514 | 0 | start = parseDate(record.get(RECORD_SUB_2_DROP_UG)); |
515 | 0 | if (start == null) { |
516 | 0 | throw new RuntimeException(recordKey); |
517 | |
} |
518 | 0 | allDay = true; |
519 | 0 | range = false; |
520 | |
|
521 | 0 | } else if (KEYDATE_GRADES_DUE_KEY.equals(keydateType)) { |
522 | 0 | start = parseDate(record.get(RECORD_SUB_2_GRADE_SUBMIT_DEADLINE_DATE), record.get(RECORD_SUB_2_GRADE_SUBMIT_DEADLINE_TIME)); |
523 | 0 | if (start == null) { |
524 | 0 | return null; |
525 | |
} |
526 | 0 | allDay = false; |
527 | 0 | range = false; |
528 | |
|
529 | |
} else { |
530 | 0 | throw new RuntimeException("Keydate type not known."); |
531 | |
} |
532 | |
|
533 | 0 | Milestone milestone = new Milestone(id, name, keydateType, descriptionPlain, descriptionFormatted, start, end, allDay, range); |
534 | 0 | return milestone; |
535 | |
} |
536 | |
|
537 | |
private Date addToDate(Date date, int field, int amount) { |
538 | 0 | if (date == null) { |
539 | 0 | return null; |
540 | |
} |
541 | 0 | Calendar cal = new GregorianCalendar(); |
542 | 0 | cal.setTime(date); |
543 | 0 | cal.add(field, amount); |
544 | 0 | return cal.getTime(); |
545 | |
} |
546 | |
private Date parseDate(String dateString) { |
547 | 0 | Date date = null; |
548 | 0 | if (dateString != null && dateString.length() > 0) { |
549 | 0 | String[] dateSegments = dateString.split("/"); |
550 | 0 | int day = Integer.parseInt(dateSegments[1]); |
551 | 0 | int month = Integer.parseInt(dateSegments[0]) - 1; |
552 | 0 | int year = Integer.parseInt(dateSegments[2]); |
553 | 0 | if (year > 99) { |
554 | 0 | throw new RuntimeException("Unexpected year format: " + dateString); |
555 | |
} |
556 | 0 | if (year > 20) { |
557 | 0 | year = 1900 + year; |
558 | |
} else { |
559 | 0 | year = 2000 + year; |
560 | |
} |
561 | 0 | Calendar cal = new GregorianCalendar(year, month, day); |
562 | 0 | date = cal.getTime(); |
563 | |
} |
564 | 0 | return date; |
565 | |
} |
566 | |
|
567 | |
private Date parseDate(String dateString, String timeString) { |
568 | 0 | Date date = null; |
569 | 0 | if (dateString != null && dateString.length() > 0 && timeString != null && timeString.length() > 0) { |
570 | 0 | while (timeString.length() < 6) { |
571 | 0 | timeString = "0" + timeString; |
572 | |
} |
573 | |
|
574 | 0 | int hour = Integer.parseInt(timeString.substring(0,2)); |
575 | 0 | int minute = Integer.parseInt(timeString.substring(2,4)); |
576 | 0 | int second = Integer.parseInt(timeString.substring(4,6)); |
577 | |
|
578 | 0 | Calendar cal = new GregorianCalendar(); |
579 | 0 | cal.setTime(parseDate(dateString)); |
580 | 0 | cal.set(Calendar.HOUR_OF_DAY, hour); |
581 | 0 | cal.set(Calendar.MINUTE, minute); |
582 | 0 | cal.set(Calendar.SECOND, second); |
583 | 0 | date = cal.getTime(); |
584 | |
} |
585 | 0 | return date; |
586 | |
} |
587 | |
|
588 | |
int getQuarter(String recordKey) { |
589 | 0 | if (recordKey.length() != 5) { |
590 | 0 | throw new IllegalArgumentException("recordKey: " + recordKey); |
591 | |
} |
592 | 0 | int quater = Integer.parseInt(recordKey.substring(4, 5)); |
593 | 0 | return quater; |
594 | |
} |
595 | |
int getYear(String recordKey) { |
596 | 0 | if (recordKey.length() != 5) { |
597 | 0 | throw new IllegalArgumentException("recordKey: " + recordKey); |
598 | |
} |
599 | 0 | int year = Integer.parseInt(recordKey.substring(0, 4)); |
600 | 0 | return year; |
601 | |
} |
602 | |
String getAtpTypeName(int quarter) { |
603 | 0 | String name = null; |
604 | 0 | switch (quarter) { |
605 | 0 | case 1: name = WINTER_ATP_TYPE; break; |
606 | 0 | case 2: name = SPRING_ATP_TYPE; break; |
607 | 0 | case 3: name = SUMMER_ATP_TYPE; break; |
608 | 0 | case 4: name = FALL_ATP_TYPE; break; |
609 | |
} |
610 | 0 | return name; |
611 | |
} |
612 | |
String getAtpTypeKey(int quarter) { |
613 | 0 | String name = null; |
614 | 0 | switch (quarter) { |
615 | 0 | case 1: name = WINTER_ATP_TYPE_KEY; break; |
616 | 0 | case 2: name = SPRING_ATP_TYPE_KEY; break; |
617 | 0 | case 3: name = SUMMER_ATP_TYPE_KEY; break; |
618 | 0 | case 4: name = FALL_ATP_TYPE_KEY; break; |
619 | |
} |
620 | 0 | return name; |
621 | |
} |
622 | |
|
623 | |
private Atp getAcalForTermId(String termId) { |
624 | 0 | if (termId.length() != 5) { |
625 | 0 | throw new IllegalArgumentException("termId: " + termId); |
626 | |
} |
627 | 0 | int year = getYear(termId); |
628 | 0 | int quater = getQuarter(termId); |
629 | 0 | if (quater < 3) { |
630 | 0 | year--; |
631 | |
} |
632 | 0 | Atp acal = allAcals.get(String.valueOf(year)); |
633 | 0 | if (acal == null) { |
634 | 0 | acal = new Atp(); |
635 | 0 | allAcals.put(String.valueOf(year), acal); |
636 | 0 | acal.setId(year + "" + (year + 1) + "ACADEMICCALENDAR"); |
637 | 0 | acal.setType("kuali.atp.type.AcademicCalendar"); |
638 | 0 | acal.setAdminOrgId("102"); |
639 | 0 | acal.setAtpCode("ACAL"+year); |
640 | 0 | acal.setName(year + "/" + (year + 1) + " Academic Calendar"); |
641 | 0 | acal.setDescriptionPlain("Academic Calendar for " + year + "/" + (year + 1)); |
642 | 0 | acal.setDescriptionFormatted("<p>" + acal.getDescriptionPlain() + "</p>"); |
643 | |
} |
644 | 0 | return acal; |
645 | |
} |
646 | |
|
647 | |
private void loadDataSet(File file) { |
648 | 0 | DataInputStream in = null; |
649 | |
try { |
650 | 0 | FileInputStream fstream = new FileInputStream(file); |
651 | 0 | in = new DataInputStream(fstream); |
652 | 0 | BufferedReader br = new BufferedReader(new InputStreamReader(in)); |
653 | |
|
654 | 0 | String[] headers = null; |
655 | |
String line; |
656 | 0 | int row = 0; |
657 | 0 | while ((line = br.readLine()) != null) { |
658 | 0 | String[] columnValues = line.split("\t"); |
659 | 0 | if (0 == row) { |
660 | 0 | headers = columnValues; |
661 | |
} else { |
662 | 0 | Map<String, String> map = new LinkedHashMap<String, String>(); |
663 | 0 | for (int i = 0; i < headers.length; i++) { |
664 | 0 | map.put(headers[i], columnValues[i]); |
665 | |
} |
666 | 0 | dataSet.add(map); |
667 | |
} |
668 | 0 | row++; |
669 | 0 | } |
670 | 0 | } catch (Exception e) { |
671 | 0 | e.printStackTrace(); |
672 | |
} finally { |
673 | 0 | if (in != null) { |
674 | |
try { |
675 | 0 | in.close(); |
676 | 0 | } catch (IOException e) { |
677 | 0 | e.printStackTrace(); |
678 | 0 | } |
679 | |
} |
680 | |
} |
681 | 0 | } |
682 | |
|
683 | |
private void writeToFile(File file, String content) { |
684 | |
try{ |
685 | 0 | FileWriter fstream = new FileWriter(file); |
686 | 0 | BufferedWriter out = new BufferedWriter(fstream); |
687 | 0 | out.write(content); |
688 | 0 | out.close(); |
689 | 0 | } catch (Exception e){ |
690 | 0 | e.printStackTrace(); |
691 | 0 | } |
692 | 0 | } |
693 | |
|
694 | |
public String getReport(List<String> years) { |
695 | 0 | StringBuilder builder = new StringBuilder(); |
696 | 0 | String tab = "\t"; |
697 | 0 | String line = "\n"; |
698 | |
|
699 | |
|
700 | 0 | for (String year : years) { |
701 | 0 | Atp acal = allAcals.get(year); |
702 | 0 | addReportLineForAtp(builder, acal); |
703 | 0 | for (Atp holiCal : acal.getHolidayCalendars()) { |
704 | 0 | addReportLineForAtp(builder, holiCal); |
705 | 0 | for (Milestone holiday : holiCal.getMilestones()) { |
706 | 0 | addReportLineForMilestone(builder, holiday); |
707 | |
} |
708 | |
} |
709 | 0 | for (Atp term : acal.getTerms()) { |
710 | 0 | addReportLineForAtp(builder, term); |
711 | 0 | for (Milestone milestone : term.getMilestones()) { |
712 | 0 | addReportLineForMilestone(builder, milestone); |
713 | |
} |
714 | 0 | for (Atp subTerm : term.getTerms()) { |
715 | 0 | addReportLineForAtp(builder, subTerm); |
716 | 0 | for (Milestone milestone : subTerm.getMilestones()) { |
717 | 0 | addReportLineForMilestone(builder, milestone); |
718 | |
} |
719 | |
|
720 | |
} |
721 | |
} |
722 | 0 | } |
723 | 0 | return builder.toString(); |
724 | |
} |
725 | |
|
726 | |
|
727 | |
private StringBuilder addReportLineForAtp(StringBuilder builder, Atp atp) { |
728 | 0 | String tab = "\t"; |
729 | 0 | String line = "\n"; |
730 | |
|
731 | 0 | if (builder == null) { |
732 | 0 | builder = new StringBuilder(); |
733 | |
} |
734 | |
|
735 | 0 | builder.append(atp.getName()).append(tab); |
736 | |
|
737 | 0 | Date startDate = atp.getStartDate(); |
738 | 0 | builder.append(getDate(startDate)).append(tab); |
739 | 0 | builder.append(tab); |
740 | |
|
741 | 0 | Date endDate = atp.getEndDate(); |
742 | 0 | builder.append(getDate(endDate)).append(tab); |
743 | 0 | builder.append(tab); |
744 | |
|
745 | 0 | builder.append(atp.getType()); |
746 | |
|
747 | 0 | builder.append(line); |
748 | 0 | return builder; |
749 | |
} |
750 | |
|
751 | |
private StringBuilder addReportLineForMilestone(StringBuilder builder, Milestone milestone) { |
752 | 0 | String tab = "\t"; |
753 | 0 | String line = "\n"; |
754 | |
|
755 | 0 | if (builder == null) { |
756 | 0 | builder = new StringBuilder(); |
757 | |
} |
758 | |
|
759 | 0 | builder.append(milestone.getName()).append(tab); |
760 | |
|
761 | 0 | Date startDate = milestone.getStartDate(); |
762 | 0 | builder.append(getDate(startDate)).append(tab); |
763 | 0 | if (!milestone.isAllDay()) { |
764 | 0 | builder.append(getTime(startDate)); |
765 | |
} |
766 | 0 | builder.append(tab); |
767 | |
|
768 | 0 | Date endDate = milestone.getEndDate(); |
769 | 0 | if (milestone.isDateRange()) { |
770 | 0 | if (endDate == null) { |
771 | 0 | throw new RuntimeException("End date not supplied for range. " + milestone.getId()); |
772 | |
} |
773 | 0 | builder.append(getDate(endDate)).append(tab); |
774 | 0 | if (!milestone.isAllDay()) { |
775 | 0 | builder.append(getTime(endDate)); |
776 | |
} |
777 | |
} else { |
778 | 0 | builder.append(tab); |
779 | 0 | if (endDate != null) { |
780 | 0 | throw new RuntimeException("End date not expected for non range. " + milestone.getId()); |
781 | |
} |
782 | |
} |
783 | 0 | builder.append(tab); |
784 | 0 | builder.append(milestone.getType()); |
785 | |
|
786 | 0 | builder.append(line); |
787 | 0 | return builder; |
788 | |
} |
789 | |
|
790 | |
private String getDate(Date date) { |
791 | 0 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); |
792 | 0 | if (date == null) { |
793 | 0 | return ""; |
794 | |
} |
795 | 0 | return dateFormat.format(date); |
796 | |
} |
797 | |
private String getTime(Date date) { |
798 | 0 | SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); |
799 | 0 | return timeFormat.format(date); |
800 | |
} |
801 | |
|
802 | |
public Atp getHolidayCalendar(String yearString) { |
803 | 0 | Atp holiCal = allHolidayCalendars.get(yearString); |
804 | 0 | int year = Integer.parseInt(yearString); |
805 | 0 | if (null == holiCal) { |
806 | 0 | holiCal = new Atp(); |
807 | 0 | holiCal.setId(year + "HOLIDAYCALENDAR"); |
808 | 0 | holiCal.setName(year + " Holiday Calendar"); |
809 | 0 | holiCal.setStartDate(new GregorianCalendar(year, Calendar.JANUARY, 1).getTime()); |
810 | 0 | holiCal.setEndDate(new GregorianCalendar(year, Calendar.DECEMBER, 31).getTime()); |
811 | 0 | holiCal.setDescriptionPlain("Holiday Calendar for " + year); |
812 | 0 | holiCal.setDescriptionFormatted("<p>" + holiCal.getDescriptionPlain() + "</p>"); |
813 | 0 | holiCal.setType("kuali.atp.type.HolidayCalendar"); |
814 | 0 | holiCal.setAtpCode("HCAL" + year); |
815 | 0 | holiCal.setAdminOrgId("102"); |
816 | |
|
817 | 0 | for (String holidayTypeKey : observedHolidays.keySet()) { |
818 | 0 | Milestone holiday = getHoliday(holidayTypeKey, year); |
819 | 0 | holiCal.addMilestone(holiday); |
820 | 0 | Milestone observedholiday = getHoliday(observedHolidays.get(holidayTypeKey), year); |
821 | 0 | if (null != observedholiday) { |
822 | 0 | holiCal.addMilestone(observedholiday); |
823 | |
} |
824 | 0 | } |
825 | 0 | allHolidayCalendars.put(yearString, holiCal); |
826 | |
} |
827 | 0 | return holiCal; |
828 | |
} |
829 | |
|
830 | |
public Milestone getHoliday(String holidayType, int year) { |
831 | 0 | if (null == holidayType) { |
832 | 0 | return null; |
833 | |
} |
834 | |
|
835 | 0 | String[] typeSplit = holidayType.split("\\."); |
836 | |
|
837 | 0 | String id = (year + typeSplit[typeSplit.length-1]).toUpperCase(); |
838 | 0 | String name = holidayNames.get(holidayType); |
839 | 0 | String descriptionPlain = name + " for " + year; |
840 | 0 | String descriptionFormatted = "<p>" + descriptionPlain + "<p>"; |
841 | |
|
842 | 0 | Date start = null; |
843 | 0 | Date end = null; |
844 | 0 | boolean allDay = true; |
845 | 0 | boolean range = false; |
846 | |
|
847 | 0 | if (HOLIDAY_NEWYEARSDAY_KEY.equals(holidayType)) { |
848 | 0 | Calendar cal = new GregorianCalendar(year, Calendar.JANUARY, 1); |
849 | 0 | start = cal.getTime(); |
850 | 0 | } else if (HOLIDAY_NEWYEARSDAYOBSERVED_KEY.equals(holidayType)) { |
851 | 0 | Milestone milestone = getHoliday(HOLIDAY_NEWYEARSDAY_KEY, year); |
852 | 0 | int offset = getWeekendOffset(milestone.getStartDate()); |
853 | 0 | if (0 == offset) { |
854 | 0 | return null; |
855 | |
} else { |
856 | 0 | start = addToDate(milestone.getStartDate(), Calendar.DATE, offset); |
857 | 0 | end = addToDate(milestone.getEndDate(), Calendar.DATE, offset); |
858 | |
} |
859 | 0 | } else if (HOLIDAY_MLKDAY_KEY.equals(holidayType)) { |
860 | 0 | start = getNthDayOfWeekInMonth(3, Calendar.MONDAY, Calendar.JANUARY, year); |
861 | 0 | } else if (HOLIDAY_PRESIDENTSDAY_KEY.equals(holidayType)) { |
862 | 0 | start = getNthDayOfWeekInMonth(3, Calendar.MONDAY, Calendar.FEBRUARY, year); |
863 | 0 | } else if (HOLIDAY_MEMORIALDAY_KEY.equals(holidayType)) { |
864 | 0 | start = getNthDayOfWeekInMonth(1, Calendar.MONDAY, Calendar.JUNE, year); |
865 | 0 | start = addToDate(start, Calendar.DATE, -7); |
866 | 0 | } else if (HOLIDAY_INDEPENDENCEDAY_KEY.equals(holidayType)) { |
867 | 0 | start = new GregorianCalendar(year, Calendar.JULY, 4).getTime(); |
868 | 0 | } else if (HOLIDAY_INDEPENDENCEDAYOBSERVED_KEY.equals(holidayType)) { |
869 | 0 | Milestone milestone = getHoliday(HOLIDAY_INDEPENDENCEDAY_KEY, year); |
870 | 0 | int offset = getWeekendOffset(milestone.getStartDate()); |
871 | 0 | if (0 == offset) { |
872 | 0 | return null; |
873 | |
} else { |
874 | 0 | start = addToDate(milestone.getStartDate(), Calendar.DATE, offset); |
875 | 0 | end = addToDate(milestone.getEndDate(), Calendar.DATE, offset); |
876 | |
} |
877 | 0 | } else if (HOLIDAY_LABORDAY_KEY.equals(holidayType)) { |
878 | 0 | start = getNthDayOfWeekInMonth(1, Calendar.MONDAY, Calendar.SEPTEMBER, year); |
879 | 0 | } else if (HOLIDAY_VETERANSDAY_KEY.equals(holidayType)) { |
880 | 0 | start = new GregorianCalendar(year, Calendar.NOVEMBER, 11).getTime(); |
881 | 0 | } else if (HOLIDAY_VETERANSDAYOBSERVED_KEY.equals(holidayType)) { |
882 | 0 | Milestone milestone = getHoliday(HOLIDAY_VETERANSDAY_KEY, year); |
883 | 0 | int offset = getWeekendOffset(milestone.getStartDate()); |
884 | 0 | if (0 == offset) { |
885 | 0 | return null; |
886 | |
} else { |
887 | 0 | start = addToDate(milestone.getStartDate(), Calendar.DATE, offset); |
888 | 0 | end = addToDate(milestone.getEndDate(), Calendar.DATE, offset); |
889 | |
} |
890 | 0 | } else if (HOLIDAY_THANKSGIVINGBREAK_KEY.equals(holidayType)) { |
891 | 0 | start = getNthDayOfWeekInMonth(4, Calendar.THURSDAY, Calendar.NOVEMBER, year); |
892 | 0 | end = addToDate(start, Calendar.DATE, 1); |
893 | 0 | range = true; |
894 | 0 | } else if (HOLIDAY_CHRISTMAS_KEY.equals(holidayType)) { |
895 | 0 | start = new GregorianCalendar(year, Calendar.DECEMBER, 25).getTime(); |
896 | 0 | } else if (HOLIDAY_CHRISTMASOBSERVED_KEY.equals(holidayType)) { |
897 | 0 | Milestone milestone = getHoliday(HOLIDAY_CHRISTMAS_KEY, year); |
898 | 0 | int offset = getWeekendOffset(milestone.getStartDate()); |
899 | 0 | if (0 == offset) { |
900 | 0 | return null; |
901 | |
} else { |
902 | 0 | start = addToDate(milestone.getStartDate(), Calendar.DATE, offset); |
903 | 0 | end = addToDate(milestone.getEndDate(), Calendar.DATE, offset); |
904 | |
} |
905 | 0 | } else { |
906 | 0 | throw new RuntimeException("Holiday type not known. " + holidayType); |
907 | |
} |
908 | |
|
909 | 0 | Milestone milestone = new Milestone(id, name, holidayType, descriptionPlain, descriptionFormatted, start, end, allDay, range); |
910 | 0 | return milestone; |
911 | |
} |
912 | |
|
913 | |
private void addMilestoneRelations(Atp term) { |
914 | 0 | List<Milestone> keyDates = term.getMilestones(); |
915 | 0 | Milestone instructionperiod = null; |
916 | 0 | for (Milestone keyDate : keyDates) { |
917 | 0 | if (KEYDATE_INSTRUCTIONAL_PERIOD_KEY.equals(keyDate.getType())) { |
918 | 0 | instructionperiod = keyDate; |
919 | 0 | break; |
920 | |
} |
921 | |
} |
922 | 0 | if (null == instructionperiod) { |
923 | 0 | throw new RuntimeException("Could not find instruction period for term: " + term.getId()); |
924 | |
} |
925 | 0 | for (Milestone keyDate : keyDates) { |
926 | 0 | if (relativeToInstructionPeriod.contains(keyDate.getType())) { |
927 | 0 | keyDate.setRelative(true); |
928 | 0 | keyDate.setRelativeMilestoneId(instructionperiod.getId()); |
929 | |
} else { |
930 | 0 | keyDate.setRelative(false); |
931 | |
} |
932 | |
} |
933 | |
|
934 | 0 | for (Atp atp : term.getTerms()) { |
935 | 0 | addMilestoneRelations(atp); |
936 | |
} |
937 | 0 | } |
938 | |
|
939 | |
private void alterEndDates(List<Atp> acals) { |
940 | 0 | for (int i = acals.size()-1; i >= 0 ; i--) { |
941 | 0 | Atp acal = acals.get(i); |
942 | 0 | if (i > 0) { |
943 | 0 | Atp prevAcal = acals.get(i-1); |
944 | 0 | Date start = acal.getStartDate(); |
945 | 0 | Date prevEndDate = addToDate(start, Calendar.DATE, -1); |
946 | 0 | prevAcal.setEndDate(prevEndDate); |
947 | 0 | List<Atp> prevTerms = prevAcal.getTerms(); |
948 | 0 | if (!prevTerms.isEmpty()) { |
949 | 0 | Atp lastPrevTerm = prevTerms.get(prevTerms.size()-1); |
950 | 0 | lastPrevTerm.setEndDate(prevEndDate); |
951 | 0 | List<Atp> prevSubTerms = lastPrevTerm.getTerms(); |
952 | 0 | if (!prevSubTerms.isEmpty()) { |
953 | 0 | Atp lastPrevTermSubTerm = prevSubTerms.get(prevSubTerms.size()-1); |
954 | 0 | lastPrevTermSubTerm.setEndDate(prevEndDate); |
955 | |
} |
956 | |
} |
957 | |
} |
958 | |
|
959 | 0 | List<Atp> terms = acal.getTerms(); |
960 | 0 | for (int j = terms.size()-1; j >= 0; j--) { |
961 | 0 | Atp term = terms.get(j); |
962 | 0 | if (j > 0) { |
963 | 0 | Atp prevTerm = terms.get(j-1); |
964 | 0 | Date prevEndDate = addToDate(term.getStartDate(), Calendar.DATE, -1); |
965 | 0 | prevTerm.setEndDate(prevEndDate); |
966 | 0 | List<Atp> prevSubTerms = prevTerm.getTerms(); |
967 | 0 | if (!prevSubTerms.isEmpty()) { |
968 | 0 | Atp lastPrevSubTerm = prevSubTerms.get(prevSubTerms.size()-1); |
969 | 0 | lastPrevSubTerm.setEndDate(prevEndDate); |
970 | |
} |
971 | |
} |
972 | |
} |
973 | |
|
974 | 0 | for (int j = terms.size()-1; j >= 0; j--) { |
975 | 0 | Atp term = terms.get(j); |
976 | 0 | if (j > 0) { |
977 | 0 | Atp prevTerm = terms.get(j-1); |
978 | 0 | Date start = term.getStartDate(); |
979 | 0 | prevTerm.setEndDate(addToDate(start, Calendar.DATE, -1)); |
980 | |
} |
981 | 0 | List<Atp> subTerms = term.getTerms(); |
982 | 0 | for (int k = subTerms.size()-1; k >= 0; k--) { |
983 | 0 | Atp subTerm = subTerms.get(k); |
984 | 0 | if (k > 0) { |
985 | 0 | Atp prevSubTerm = subTerms.get(k-1); |
986 | 0 | Date start = subTerm.getStartDate(); |
987 | 0 | prevSubTerm.setEndDate(addToDate(start, Calendar.DATE, -1)); |
988 | |
} |
989 | |
} |
990 | |
} |
991 | |
} |
992 | 0 | } |
993 | |
|
994 | |
private int getWeekendOffset(Date date) { |
995 | 0 | Calendar cal = new GregorianCalendar(); |
996 | 0 | cal.setTime(date); |
997 | 0 | int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); |
998 | 0 | if (Calendar.SATURDAY == dayOfWeek) { |
999 | 0 | return -1; |
1000 | 0 | } else if (Calendar.SUNDAY == dayOfWeek) { |
1001 | 0 | return 1; |
1002 | |
} else { |
1003 | 0 | return 0; |
1004 | |
} |
1005 | |
} |
1006 | |
|
1007 | |
private Date getNthDayOfWeekInMonth(int n, int dayOfWeek, int month, int year) { |
1008 | 0 | Calendar cal = new GregorianCalendar(year, month, 1); |
1009 | 0 | if (dayOfWeek != cal.get(Calendar.DAY_OF_WEEK)) { |
1010 | 0 | int daysUntil = (dayOfWeek - cal.get(Calendar.DAY_OF_WEEK) + 7) % 7; |
1011 | 0 | cal.add(Calendar.DATE, daysUntil); |
1012 | |
} |
1013 | 0 | cal.add(Calendar.DATE, (n-1) * 7); |
1014 | 0 | return cal.getTime(); |
1015 | |
} |
1016 | |
|
1017 | |
} |