package gov.nysenate.openleg.processor.entity;
import gov.nysenate.openleg.model.base.SessionYear;
import gov.nysenate.openleg.model.entity.*;
import gov.nysenate.openleg.model.sobi.SobiFragment;
import gov.nysenate.openleg.model.sobi.SobiFragmentType;
import gov.nysenate.openleg.processor.base.AbstractDataProcessor;
import gov.nysenate.openleg.processor.sobi.SobiProcessor;
import gov.nysenate.openleg.model.entity.MemberNotFoundEx;
import gov.nysenate.openleg.service.entity.member.data.MemberService;
import gov.nysenate.openleg.util.XmlHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.annotation.PostConstruct;
import javax.xml.xpath.XPathExpressionException;
import java.text.ParseException;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
@Service
public class CommitteeProcessor extends AbstractDataProcessor implements SobiProcessor
{
private static final Logger logger = Logger.getLogger(CommitteeProcessor.class);
private static final DateTimeFormatter meetTimeSDF = DateTimeFormatter.ofPattern("hh:mm a");
@Autowired
protected MemberService memberService;
@Autowired
protected XmlHelper xml;
@PostConstruct
public void init() {
initBase();
}
/** {@inheritDoc */
@Override
public SobiFragmentType getSupportedType() {
return SobiFragmentType.COMMITTEE;
}
/** {@inheritDoc */
@Override
public void process(SobiFragment sobiFragment) {
logger.info("Called committee processor");
String xmlString = sobiFragment.getText();
try {
Document doc = xml.parse(xmlString);
Node dataRoot = xml.getNode("SENATEDATA",doc);
Node committeeRoot = xml.getNode("sencommmem", dataRoot);
SessionYear sessionYear = new SessionYear(Integer.parseInt(xml.getString("@sessyr", committeeRoot)));
int year = Integer.parseInt(xml.getString("@year", committeeRoot));
Chamber chamber = Chamber.SENATE;
logger.info("Processing " + chamber + "committees for s" + sessionYear + " y" + year + "\t" +
sobiFragment.getPublishedDateTime());
committeeRoot = xml.getNode("committees", committeeRoot);
NodeList committeeNodes = committeeRoot.getChildNodes();
for(int i = 0; i < committeeNodes.getLength() ; i++){
Node committeeNode = committeeNodes.item(i);
if (committeeNode.getNodeName().equals("committee")) {
try {
Committee committee = new Committee();
committee.setSession(sessionYear);
committee.setPublishedDateTime(sobiFragment.getPublishedDateTime());
committee.setChamber(chamber);
processCommittee(committeeNode, committee);
committeeDataService.saveCommittee(committee, sobiFragment);
}
catch (Exception e){
logger.error(e);
}
}
}
}
catch (Exception e) {
logger.error(e);
}
}
@Override
public void postProcess() {}
/** --- Internal Methods --- */
private Committee processCommittee(Node committeeNode, Committee committee) throws XPathExpressionException,
ParseException {
committee.setName(xml.getString("name/text()", committeeNode));
committee.setLocation(xml.getString("location/text()", committeeNode));
String meetDay = xml.getString("meetday/text()", committeeNode);
committee.setMeetDay(StringUtils.isNotEmpty(meetDay) ? DayOfWeek.valueOf(meetDay.toUpperCase()) : null);
String meetTimeStr = xml.getString("meettime/text()", committeeNode);
committee.setMeetTime(StringUtils.isNotEmpty(meetTimeStr) ? LocalTime.parse(meetTimeStr, meetTimeSDF) : null);
committee.setMeetAltWeek(xml.getString("meetaltweek/text()", committeeNode).trim().equalsIgnoreCase("Yes"));
committee.setMeetAltWeekText(xml.getString("meetaltweektext/text()", committeeNode));
Node committeeMembership = xml.getNode("membership", committeeNode);
committee.setMembers(processCommitteeMembers(committeeMembership, committee));
return committee;
}
private List<CommitteeMember> processCommitteeMembers(Node committeeMembership, Committee committee)
throws XPathExpressionException {
List<CommitteeMember> committeeMembers = new ArrayList<CommitteeMember>();
NodeList committeeMembersNodes = committeeMembership.getChildNodes();
for(int i = 0; i < committeeMembersNodes.getLength(); i++){
Node memberNode = committeeMembersNodes.item(i);
if (memberNode.getNodeName().equals("member")) {
String shortName = xml.getString("name/text()", memberNode);
SessionMember sessionMember;
try {
sessionMember = memberService.getMemberByShortName(shortName, committee.getSession(),
committee.getChamber());
}
catch (MemberNotFoundEx memberNotFoundEx) {
logger.error("Could not identify committee member " + shortName + " " + committee.getSession() +
" " + committee.getChamber());
continue;
}
CommitteeMember committeeMember = new CommitteeMember();
committeeMember.setSequenceNo(Integer.parseInt(xml.getString("@seqno", memberNode)));
committeeMember.setMember(sessionMember);
committeeMember.setMajority(
xml.getString("memberlist/text()", memberNode).trim().equalsIgnoreCase("Majority"));
String title = xml.getString("title/text()", memberNode).trim();
if (title.equalsIgnoreCase("Chairperson")) {
committeeMember.setTitle(CommitteeMemberTitle.CHAIR_PERSON);
}
else if (title.equalsIgnoreCase("Vice-Chair")) {
committeeMember.setTitle(CommitteeMemberTitle.VICE_CHAIR);
}
else {
committeeMember.setTitle(CommitteeMemberTitle.MEMBER);
}
committeeMembers.add(committeeMember);
}
}
return committeeMembers;
}
}