Java tutorial
/* * Unless explicitly acquired and licensed from Licensor under another license, the contents of * this file are subject to the Reciprocal Public License ("RPL") Version 1.5, or subsequent * versions as allowed by the RPL, and You may not copy or use this file in either source code * or executable form, except in compliance with the terms and conditions of the RPL * * All software distributed under the RPL is provided strictly on an "AS IS" basis, WITHOUT * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND LICENSOR HEREBY DISCLAIMS ALL SUCH * WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the RPL for specific language * governing rights and limitations under the RPL. * * http://opensource.org/licenses/RPL-1.5 * * Copyright 2012-2015 Open Justice Broker Consortium */ package org.ojbc.adapters.analyticsstaging.custody.processor; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ojbc.adapters.analyticsstaging.custody.dao.model.Address; import org.ojbc.adapters.analyticsstaging.custody.dao.model.Booking; import org.ojbc.adapters.analyticsstaging.custody.dao.model.BookingArrest; import org.ojbc.adapters.analyticsstaging.custody.dao.model.BookingCharge; import org.ojbc.adapters.analyticsstaging.custody.dao.model.CodeTable; import org.ojbc.adapters.analyticsstaging.custody.dao.model.KeyValue; import org.ojbc.util.xml.XmlUtils; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @Component public class BookingReportProcessor extends AbstractReportRepositoryProcessor { private static final Log log = LogFactory.getLog(BookingReportProcessor.class); @Transactional(rollbackFor = Exception.class) public void processReport(Document report) throws Exception { log.info("Processing booking report."); XmlUtils.printNode(report); Booking booking = processBookingReport(report); processBookingArrests(report, booking.getBookingId()); analyticalDatastoreDAO.updateCustodyReleaseBookingId(booking.getBookingId(), booking.getBookingNumber()); analyticalDatastoreDAO.updateCustodyStatusChangeBookingId(booking.getBookingId(), booking.getBookingNumber()); log.info("Processed booking report."); } private void processBookingArrests(Document report, Integer bookingId) throws Exception { NodeList locationNodes = XmlUtils.xPathNodeListSearch(report, "/br-doc:BookingReport/nc30:Location[@s30:id = /br-doc:BookingReport/jxdm51:Arrest/jxdm51:ArrestLocation/@s30:ref]"); Map<String, Integer> addressMap = constructAddressMap(locationNodes); NodeList arrestNodes = XmlUtils.xPathNodeListSearch(report, "/br-doc:BookingReport/jxdm51:Arrest[@s30:id = preceding-sibling::jxdm51:Booking/jxdm51:Arrest/@s30:ref]"); for (int i = 0; i < arrestNodes.getLength(); i++) { Node arrestNode = arrestNodes.item(i); if (arrestNode != null) { Integer bookingArrestId = processBookingArrest(arrestNode, bookingId, addressMap); processBookingCharges(arrestNode, bookingArrestId); } } } private Integer processBookingArrest(Node arrestNode, Integer bookingId, Map<String, Integer> addressMap) throws Exception { BookingArrest bookingArrest = new BookingArrest(); bookingArrest.setBookingId(bookingId); String arrestAgency = XmlUtils.xPathStringSearch(arrestNode, "jxdm51:ArrestAgency/nc30:OrganizationName"); bookingArrest.setArrestAgencyId(descriptionCodeLookupService.retrieveCode(CodeTable.Agency, arrestAgency)); String locationRef = XmlUtils.xPathStringSearch(arrestNode, "jxdm51:ArrestLocation/@s30:ref"); bookingArrest.setAddress(new Address(addressMap.get(locationRef))); Integer bookingArrestId = analyticalDatastoreDAO.saveBookingArrest(bookingArrest); return bookingArrestId; } private void processBookingCharges(Node arrestNode, Integer bookingArrestId) throws Exception { NodeList chargeRefNodes = XmlUtils.xPathNodeListSearch(arrestNode, "jxdm51:ArrestCharge/@s30:ref"); List<BookingCharge> bookingCharges = new ArrayList<BookingCharge>(); for (int i = 0; i < chargeRefNodes.getLength(); i++) { Attr chargeRefNode = (Attr) chargeRefNodes.item(i); String chargeRef = chargeRefNode.getValue(); Node chargeNode = XmlUtils.xPathNodeSearch(arrestNode, "parent::br-doc:BookingReport/jxdm51:Charge[@s30:id = '" + chargeRef + "']"); if (chargeNode != null) { BookingCharge bookingCharge = new BookingCharge(); bookingCharge.setBookingArrestId(bookingArrestId); String sendingAgency = XmlUtils.xPathStringSearch(chargeNode, "br-ext:HoldForAgency/nc30:OrganizationName"); bookingCharge .setAgencyId(descriptionCodeLookupService.retrieveCode(CodeTable.Agency, sendingAgency)); bookingCharge.setChargeCode(XmlUtils.xPathStringSearch(chargeNode, "jxdm51:ChargeStatute/jxdm51:StatuteCodeSectionIdentification/nc30:IdentificationID")); bookingCharge.setChargeDisposition( XmlUtils.xPathStringSearch(chargeNode, "jxdm51:ChargeDisposition/nc30:DispositionText")); String chargeClassType = XmlUtils.xPathStringSearch(chargeNode, "jxdm51:ChargeSeverityText"); bookingCharge.setChargeClassTypeId( descriptionCodeLookupService.retrieveCode(CodeTable.ChargeClassType, chargeClassType)); setBondInfo(chargeNode, chargeRef, bookingCharge); String chargeJurisdictionType = XmlUtils.xPathStringSearch(chargeNode, "br-ext:ChargeJurisdictionCourt/jxdm51:CourtName"); bookingCharge.setChargeJurisdictionTypeId((descriptionCodeLookupService .retrieveCode(CodeTable.JurisdictionType, chargeJurisdictionType))); bookingCharges.add(bookingCharge); } } analyticalDatastoreDAO.saveBookingCharges(bookingCharges); } private void setBondInfo(Node chargeNode, String chargeRef, BookingCharge bookingCharge) throws Exception { String bondId = XmlUtils.xPathStringSearch(chargeNode, "parent::br-doc:BookingReport/" + "jxdm51:BailBondChargeAssociation[jxdm51:Charge/@s30:ref='" + chargeRef + "']/jxdm51:BailBond/@s30:ref"); if (StringUtils.isNotBlank(bondId)) { Node bondNode = XmlUtils.xPathNodeSearch(chargeNode, "parent::br-doc:BookingReport/jxdm51:BailBond[@s30:id = '" + bondId + "']"); String bondType = XmlUtils.xPathStringSearch(bondNode, "nc30:ActivityCategoryText"); Integer bondTypeId = descriptionCodeLookupService.retrieveCode(CodeTable.BondType, bondType); KeyValue keyValue = new KeyValue(bondTypeId, bondType); bookingCharge.setBondType(keyValue); String bondAmount = XmlUtils.xPathStringSearch(bondNode, "jxdm51:BailBondAmount/nc30:Amount"); if (StringUtils.isNotBlank(bondAmount)) { bookingCharge.setBondAmount(new BigDecimal(bondAmount)); } String bondStatusType = XmlUtils.xPathStringSearch(bondNode, "nc30:ActivityStatus/nc30:StatusDescriptionText"); bookingCharge.setBondStatusTypeId( descriptionCodeLookupService.retrieveCode(CodeTable.BondStatusType, bondStatusType)); } } @Transactional private Booking processBookingReport(Document report) throws Exception { Node bookingReportNode = XmlUtils.xPathNodeSearch(report, "/br-doc:BookingReport"); String bookingNumber = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Booking/jxdm51:BookingAgencyRecordIdentification/nc30:IdentificationID"); checkBookingNumber(bookingNumber); Booking booking = new Booking(); booking.setBookingNumber(bookingNumber); Integer personId = processPersonAndBehavioralHealthInfo(report); booking.setPersonId(personId); String bookingDateTimeString = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Booking/nc30:ActivityDate/nc30:DateTime"); LocalDateTime bookingDateTime = parseLocalDateTime(bookingDateTimeString); if (bookingDateTime != null) { booking.setBookingDate(bookingDateTime.toLocalDate()); booking.setBookingTime(bookingDateTime.toLocalTime()); } else { String bookingDateString = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Booking/nc30:ActivityDate/nc30:Date"); booking.setBookingDate(parseLocalDate(bookingDateString)); } String facility = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Booking/jxdm51:BookingDetentionFacility/nc30:FacilityIdentification/nc30:IdentificationID"); Integer facilityId = descriptionCodeLookupService.retrieveCode(CodeTable.Facility, facility); booking.setFacilityId(facilityId); String supervisionUnitType = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Detention/jxdm51:SupervisionAugmentation/jxdm51:SupervisionAreaIdentification/nc30:IdentificationID"); Integer supervisionUnitTypeId = descriptionCodeLookupService.retrieveCode(CodeTable.SupervisionUnitType, supervisionUnitType); booking.setSupervisionUnitTypeId(supervisionUnitTypeId); String supervisionReleaseEligibilityDate = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Detention/jxdm51:SupervisionAugmentation/jxdm51:SupervisionReleaseEligibilityDate/nc30:Date"); booking.setScheduledReleaseDate(parseLocalDate(supervisionReleaseEligibilityDate)); String inmateJailResidentIndicator = XmlUtils.xPathStringSearch(bookingReportNode, "jxdm51:Detention/br-ext:InmateJailResidentIndicator"); booking.setInmateJailResidentIndicator(BooleanUtils.toBooleanObject(inmateJailResidentIndicator)); Integer bookingId = analyticalDatastoreDAO.saveBooking(booking); booking.setBookingId(bookingId); processCustodyReleaseInfo(bookingReportNode, bookingId, bookingNumber); return booking; } /** * If bookingNumber already exists in the database, clean up the DB by wiping out all persisted data for the booking number. * * @param bookingNumber * @throws Exception if bookingNumber is empty */ private void checkBookingNumber(String bookingNumber) throws Exception { if (StringUtils.isBlank(bookingNumber)) { log.fatal(BOOKING_NUMBER_IS_MISSING_IN_THE_REPORT); throw new Exception(BOOKING_NUMBER_IS_MISSING_IN_THE_REPORT); } Integer existingBookingId = analyticalDatastoreDAO.getBookingIdByBookingNumber(bookingNumber); if (existingBookingId != null) { analyticalDatastoreDAO.deleteBooking(existingBookingId); } } private Integer processPersonAndBehavioralHealthInfo(Document report) throws Exception { Node personNode = XmlUtils.xPathNodeSearch(report, "/br-doc:BookingReport/nc30:Person[@s30:id=/br-doc:BookingReport/jxdm51:Booking/jxdm51:BookingSubject/nc30:RoleOfPerson/@s30:ref]"); String personUniqueIdentifier = getPersonUniqueIdentifier(personNode, "br-ext:PersonPersistentIdentification/nc30:IdentificationID"); Integer personId = savePerson(personNode, personUniqueIdentifier, "br-ext"); processBehavioralHealthInfo(personNode, personId, "br-ext"); return personId; } }