package gov.nysenate.openleg.dao.hearing; import gov.nysenate.openleg.dao.base.LimitOffset; import gov.nysenate.openleg.dao.base.SqlBaseDao; import gov.nysenate.openleg.model.hearing.PublicHearingFile; import gov.nysenate.openleg.util.FileIOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.stereotype.Repository; import javax.annotation.PostConstruct; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import static gov.nysenate.openleg.dao.hearing.SqlPublicHearingFileQuery.*; import static gov.nysenate.openleg.util.DateUtils.toDate; @Repository public class SqlFsPublicHearingFileDao extends SqlBaseDao implements PublicHearingFileDao { private static final Logger logger = LoggerFactory.getLogger(SqlFsPublicHearingFileDao.class); /** Directory were new PublicHearingFiles come in from external sources. */ private File incomingPublicHearingDir; /** Directory where we store PublicHearingFiles that have been processed. */ private File archivePublicHearingDir; @PostConstruct private void init() { incomingPublicHearingDir = new File(environment.getStagingDir(), "hearing_transcripts"); archivePublicHearingDir = new File(environment.getArchiveDir(), "hearing_transcripts"); } /** --- Implemented Methods --- */ /** {@inheritDoc} */ @Override public List<PublicHearingFile> getIncomingPublicHearingFiles(LimitOffset limOff) throws IOException { List<File> files = new ArrayList<>(FileIOUtils.safeListFiles(incomingPublicHearingDir, false, null)); files = LimitOffset.limitList(files, limOff); List<PublicHearingFile> publicHearingFiles = new ArrayList<>(); for (File file : files) { publicHearingFiles.add(new PublicHearingFile(file)); } return publicHearingFiles; } /** {@inheritDoc} */ @Override public void updatePublicHearingFile(PublicHearingFile publicHearingFile) { MapSqlParameterSource params = getPublicHearingFileParams(publicHearingFile); if (jdbcNamed.update(UPDATE_PUBLIC_HEARING_FILE.getSql(schema()), params) == 0) { jdbcNamed.update(INSERT_PUBLIC_HEARING_FILE.getSql(schema()), params); } } /** {@inheritDoc} */ @Override public void archivePublicHearingFile(PublicHearingFile publicHearingFile) throws IOException { File stagedFile = publicHearingFile.getFile(); if (stagedFile.getParentFile().compareTo(incomingPublicHearingDir) == 0) { File archiveFile = new File(archivePublicHearingDir, publicHearingFile.getFileName()); moveFile(stagedFile, archiveFile); publicHearingFile.setFile(archiveFile); publicHearingFile.setArchived(true); updatePublicHearingFile(publicHearingFile); } else { throw new FileNotFoundException("PublicHearingFile " + stagedFile + " must be in the incoming" + "hearings directory in order to be archived."); } } /** {@inheritDoc} */ @Override public List<PublicHearingFile> getPendingPublicHearingFile(LimitOffset limOff) { return jdbcNamed.query(SELECT_PENDING_PUBLIC_HEARING_FILES.getSql(schema(), limOff), new PublicHearingFileRowMapper()); } /** --- Internal Methods --- */ private File getFileInArchiveDir(String fileName) { return new File(archivePublicHearingDir, fileName); } private File getFileInIncomingDir(String fileName) { return new File(incomingPublicHearingDir, fileName); } /** --- Helper Classes --- */ protected class PublicHearingFileRowMapper implements RowMapper<PublicHearingFile> { @Override public PublicHearingFile mapRow(ResultSet rs, int i) throws SQLException { String fileName = rs.getString("filename"); boolean archived = rs.getBoolean("archived"); File file = archived ? getFileInArchiveDir(fileName) : getFileInIncomingDir(fileName); PublicHearingFile publicHearingFile = null; try { publicHearingFile = new PublicHearingFile(file); publicHearingFile.setProcessedDateTime(getLocalDateTimeFromRs(rs, "processed_date_time")); publicHearingFile.setProcessedCount(rs.getInt("processed_count")); publicHearingFile.setStagedDateTime(getLocalDateTimeFromRs(rs, "staged_date_time")); publicHearingFile.setPendingProcessing(rs.getBoolean("pending_processing")); publicHearingFile.setArchived(rs.getBoolean("archived")); } catch (FileNotFoundException ex) { logger.error("PublicHearing File " + fileName + " was not found in the expected location.", ex); } return publicHearingFile; } } /** --- Param Source Methods --- */ private MapSqlParameterSource getPublicHearingFileParams(PublicHearingFile publicHearingFile) { MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("fileName", publicHearingFile.getFileName()); params.addValue("processedDateTime", toDate(publicHearingFile.getProcessedDateTime())); params.addValue("processedCount", publicHearingFile.getProcessedCount()); params.addValue("pendingProcessing", publicHearingFile.isPendingProcessing()); params.addValue("archived", publicHearingFile.isArchived()); return params; } }