package smash.appointment.parse; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.text.SimpleDateFormat; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import org.apache.log4j.Logger; public class RedcapCalendarParser { Logger logger = Logger.getLogger(RedcapCalendarParser.class); private SubjectDao subjectDao; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); public List<AppointmentEntry> parse(String filename, Calendar minDate) throws FileNotFoundException, IOException { List<AppointmentEntry> result = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(filename))) { String line; while ((line = br.readLine()) != null) { if (!line.startsWith("INSERT INTO")) { continue; } String tmp[] = line.substring(line.indexOf("(")).split("\\),\\(", -1); for (String string : tmp) { AppointmentEntry entry = processEntry(string, minDate); if (entry != null) { result.add(entry); } } } } return result; } private AppointmentEntry processEntry(String string, Calendar minDate) { AppointmentEntry result = new AppointmentEntry(); if (string.startsWith("(")) { string = string.substring(1); } if (string.endsWith(")")) { string = string.substring(0, string.length() - 1); } string = string.replaceAll("\\\\'", "__quota__"); string = string.replaceAll("'", "\""); string = string.replaceAll("__quota__", "'"); String fields[] = string.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1); String ndNumber = fields[1].replaceAll("\"", ""); String day = fields[6].replaceAll("\"", ""); String time = fields[7].replaceAll("\"", ""); String query = fields[10].replaceAll("\"", ""); if (query.equals("") || query.equals("NULL")) { return null; } if (minDate != null) { if (day.compareTo(dateFormatter.format(minDate.getTime())) < 0) { return null; } } if (ndNumber.equals("NDtest_internal") || ndNumber.equals("NDtest_external")) { return null; } Subject subject = null; if (!ndNumber.equalsIgnoreCase("NULL")) { subject = subjectDao.getByNdNumber(ndNumber); if (subject == null) { logger.warn("Cannot find subject with nd number: " + ndNumber); } } if (subject == null) { subject = findSubject(query); } if (subject != null && !subject.getToBeSeenAt().toLowerCase().startsWith("l")) { return null; } result.setLocation("LIH"); result.setDay(day); result.setTime(time); result.setSource("From redcap: " + query); result.setSubject(subject); result.addTypes(getTypes(query)); if (result.getTypes().contains(AppointmentType.OTHER)) { logger.warn("Cannot find types for: " + query); } if (result.getTypes().contains(AppointmentType.LEVEL_ASAMP)) { return result; } else { logger.debug("Skipping LIH appointment: " + query); return null; } } CellParser cellParser = new CellParser(); private List<AppointmentType> getTypes(String query) { List<AppointmentType> result = new ArrayList<>(); AppointmentTypeCollection collection = cellParser.extractType(query); if (collection == null) { int index = query.indexOf("_"); if (index >= 0) { query = query.substring(index); if (query.startsWith("_lev a_")) { collection = AppointmentTypeCollection.LEVEL_A; } else { index = query.indexOf("_", 1); if (index >= 0) { query = query.substring(index); if (query.startsWith("_lev a_")) { collection = AppointmentTypeCollection.LEVEL_A; } } } } if (collection == null) { collection = AppointmentTypeCollection.OTHER; } } for (AppointmentType appointmentType : collection.getTypes()) { result.add(appointmentType); } return result; } private Subject findSubject(String query) { String id = query.split("_")[0]; id = "L-" + id; Subject result = subjectDao.getByScreeningNumber(id); if (result == null) { logger.warn("Cannot find subject for query: " + query); } return result; } /** * @return the subjectDao * @see #subjectDao */ public SubjectDao getSubjectDao() { return subjectDao; } /** * @param subjectDao * the subjectDao to set * @see #subjectDao */ public void setSubjectDao(SubjectDao subjectDao) { this.subjectDao = subjectDao; } }