package gov.nysenate.openleg.script; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import gov.nysenate.openleg.model.base.SessionYear; import gov.nysenate.openleg.model.entity.*; import gov.nysenate.openleg.service.entity.committee.data.CommitteeDataService; import gov.nysenate.openleg.model.entity.MemberNotFoundEx; import gov.nysenate.openleg.service.entity.member.data.MemberService; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; import java.io.File; import java.io.FilenameFilter; import java.time.LocalDate; import java.util.*; @Component public class ImportCommittees extends BaseScript { private static final Logger logger = LoggerFactory.getLogger(ImportCommittees.class); private static FilenameFilter intFileNameFilter = (File dir, String name) -> StringUtils.isNumeric(name); private static FilenameFilter jsonFileNameFilter = (File dir, String name) -> name.endsWith(".json"); @Autowired CommitteeDataService committeeDataService; @Autowired MemberService memberService; public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext ctx = init(); ImportCommittees importCommittees = ctx.getBean(ImportCommittees.class); CommandLine cmd = getCommandLine(importCommittees.getOptions(), args); importCommittees.execute(cmd); shutdown(ctx); } @Override protected Options getOptions() { Options options = super.getOptions(); options.addOption(new Option("d", "committeeDir", true, "Path to the root committee json directory")); return options; } @Override protected void execute(CommandLine opts) throws Exception { File committeeDir = new File(opts.getOptionValue("committeeDir")); if (committeeDir.isDirectory()) { List<File> yearDirs = Arrays.asList(committeeDir.listFiles(intFileNameFilter)); yearDirs.sort((File f1, File f2 ) -> ((Integer) Integer.parseInt(f1.getName())).compareTo(Integer.parseInt(f2.getName()))); for (File yearDir : committeeDir.listFiles(intFileNameFilter)) { int year = Integer.parseInt(yearDir.getName()); if (yearDir.isDirectory()) { for (File jsonFile : yearDir.listFiles(jsonFileNameFilter)) { try { logger.info("importing " + year + "/" + jsonFile.getName()); Committee committee = getCommitteeFromJson(jsonFile, year, Chamber.SENATE); committeeDataService.saveCommittee(committee, null); logger.info("inserted committee: " + committee.getVersionId()); } catch (DataAccessException ex) { logger.warn("Error storing committee: "); ex.printStackTrace(); System.exit(-1); } catch (Exception ex) { logger.warn("invalid committee json file: " + jsonFile.getAbsolutePath()); ex.printStackTrace(); System.exit(-1); } } } } } } private Committee getCommitteeFromJson(File jsonFile, int year, Chamber chamber) throws Exception{ ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(jsonFile); Committee committee = new Committee(); committee.setName(root.get("name").textValue()); committee.setChamber(chamber); committee.setSession(SessionYear.of(year)); committee.setPublishedDateTime(LocalDate.of(year, 1, 1).atStartOfDay()); int sequenceNum = 1; List<CommitteeMember> committeeMembers = new ArrayList<>(); Set<SessionMember> addedMembers = new HashSet<>(); // Used to prevent the same member from being added multiple times Iterator<JsonNode> chairs = root.path("chairs").elements(); while (chairs.hasNext()) { try { CommitteeMember committeeMember = getCommitteeMemberFromJson(chairs.next(), year, chamber); committeeMember.setTitle(sequenceNum == 1 ? CommitteeMemberTitle.CHAIR_PERSON : CommitteeMemberTitle.VICE_CHAIR); if (!addedMembers.contains(committeeMember.getMember())) { committeeMember.setSequenceNo(sequenceNum++); committeeMembers.add(committeeMember); addedMembers.add(committeeMember.getMember()); } } catch (MemberNotFoundEx ex) { ex.printStackTrace(); } } Iterator<JsonNode> members = root.get("members").elements(); while (members.hasNext()) { try { CommitteeMember committeeMember = getCommitteeMemberFromJson(members.next(), year, chamber); committeeMember.setTitle(CommitteeMemberTitle.MEMBER); if (!addedMembers.contains(committeeMember.getMember())) { committeeMember.setSequenceNo(sequenceNum++); committeeMembers.add(committeeMember); addedMembers.add(committeeMember.getMember()); } } catch (MemberNotFoundEx ex) { ex.printStackTrace(); } } committee.setMembers(committeeMembers); return committee; } private CommitteeMember getCommitteeMemberFromJson(JsonNode memberNode, int year, Chamber chamber) throws MemberNotFoundEx{ CommitteeMember committeeMember = new CommitteeMember(); SessionMember member = memberService.getMemberByShortName(memberNode.get("shortName").textValue(), SessionYear.of(year), chamber); committeeMember.setMember(member); return committeeMember; } }