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.web.portal.controllers; import static org.ojbc.util.helper.UniqueIdUtils.getFederatedQueryId; import java.io.StringReader; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.json.JSONArray; import org.json.JSONObject; import org.ojbc.processor.subscription.subscribe.SubscriptionResponseProcessor; import org.ojbc.processor.subscription.validation.SubscriptionValidationResponseProcessor; import org.ojbc.util.xml.XmlUtils; import org.ojbc.web.OJBCWebServiceURIs; import org.ojbc.web.SubscriptionInterface; import org.ojbc.web.model.person.query.DetailsRequest; import org.ojbc.web.model.person.search.PersonSearchRequest; import org.ojbc.web.model.subscription.Subscription; import org.ojbc.web.model.subscription.Unsubscription; import org.ojbc.web.model.subscription.add.SubscriptionEndDateStrategy; import org.ojbc.web.model.subscription.add.SubscriptionStartDateStrategy; import org.ojbc.web.model.subscription.response.SubscriptionAccessDenialResponse; import org.ojbc.web.model.subscription.response.SubscriptionInvalidEmailResponse; import org.ojbc.web.model.subscription.response.SubscriptionInvalidSecurityTokenResponse; import org.ojbc.web.model.subscription.response.SubscriptionRequestErrorResponse; import org.ojbc.web.model.subscription.response.UnsubscriptionAccessDenialResponse; import org.ojbc.web.model.subscription.response.common.FaultableSoapResponse; import org.ojbc.web.model.subscription.response.common.SubscriptionResponse; import org.ojbc.web.model.subscription.response.common.SubscriptionResponseType; import org.ojbc.web.model.subscription.validation.SubscriptionValidationResponse; import org.ojbc.web.portal.controllers.config.PeopleControllerConfigInterface; import org.ojbc.web.portal.controllers.config.SubscriptionsControllerConfigInterface; import org.ojbc.web.portal.controllers.dto.SubscriptionFilterCommand; import org.ojbc.web.portal.controllers.helpers.DateTimeJavaUtilPropertyEditor; import org.ojbc.web.portal.controllers.helpers.DateTimePropertyEditor; import org.ojbc.web.portal.controllers.helpers.SubscribedPersonNames; import org.ojbc.web.portal.controllers.helpers.SubscriptionQueryResultsProcessor; import org.ojbc.web.portal.controllers.helpers.UserSession; import org.ojbc.web.portal.services.SamlService; import org.ojbc.web.portal.services.SearchResultConverter; import org.ojbc.web.portal.validators.ChCycleSubscriptionValidator; import org.ojbc.web.portal.validators.IncidentSubscriptionAddValidator; import org.ojbc.web.portal.validators.IncidentSubscriptionEditValidator; import org.ojbc.web.portal.validators.subscriptions.ArrestSubscriptionValidatorInterface; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.SessionAttributes; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; @Controller @Profile({ "subscriptions", "standalone" }) @RequestMapping("/subscriptions/*") @SessionAttributes("subscription") public class SubscriptionsController { public static final String ARREST_TOPIC_SUB_TYPE = "{http://ojbc.org/wsn/topics}:person/arrest"; public static final String INCIDENT_TOPIC_SUB_TYPE = "{http://ojbc.org/wsn/topics}:person/incident"; public static final String CHCYCLE_TOPIC_SUB_TYPE = "{http://ojbc.org/wsn/topics}:person/criminalHistoryCycleTrackingIdentifierAssignment"; private static DocumentBuilder docBuilder; private Logger logger = Logger.getLogger(SubscriptionsController.class.getName()); @Value("${validateSubscriptionButton:false}") String validateSubscriptionButton; @Resource Map<String, SubscriptionStartDateStrategy> subscriptionStartDateStrategyMap; @Resource Map<String, SubscriptionEndDateStrategy> subscriptionEndDateStrategyMap; @Resource Map<String, SubscriptionStartDateStrategy> editSubscriptionStartDateStrategyMap; @Resource Map<String, String> subscriptionDefaultsMap; @Resource Map<String, String> subscriptionFilterProperties; @Resource UserSession userSession; @Resource SamlService samlService; //TODO see if edit validator needs injection also @Value("#{getObject('arrestSubscriptionAddValidator')}") ArrestSubscriptionValidatorInterface arrestSubscriptionAddValidator; @Resource ArrestSubscriptionValidatorInterface arrestSubscriptionEditValidator; @Resource IncidentSubscriptionAddValidator incidentSubscriptionAddValidator; @Resource ChCycleSubscriptionValidator chCycleSubscriptionValidator; @Resource IncidentSubscriptionEditValidator incidentSubscriptionEditValidator; @Resource SearchResultConverter searchResultConverter; @Resource Map<String, String> subscriptionTypeValueToLabelMap; @Resource Map<String, String> subscriptionPurposeValueToLabelMap; @Resource PeopleControllerConfigInterface config; @Resource SubscriptionsControllerConfigInterface subConfig; @ModelAttribute("subscriptionFilterProperties") public Map<String, String> getSubscriptionFilterProperties() { return subscriptionFilterProperties; } @RequestMapping(value = "subscriptionResults", method = RequestMethod.POST) public String searchSubscriptions(HttpServletRequest request, Map<String, Object> model) { Element samlElement = samlService.getSamlAssertion(request); String searchId = getFederatedQueryId(); String rawResults = null; String informationMessage = ""; try { rawResults = subConfig.getSubscriptionSearchBean().invokeSubscriptionSearchRequest(searchId, samlElement); userSession.setMostRecentSubscriptionSearchResult(rawResults); userSession.setSavedMostRecentSubscriptionSearchResult(null); } catch (Exception e) { informationMessage = "Failed retrieving subscriptions"; e.printStackTrace(); } logger.info("Subscription results raw xml:\n" + rawResults); Map<String, Object> subResultsHtmlXsltParamMap = getParams(0, null, null); subResultsHtmlXsltParamMap.put("messageIfNoResults", "You do not have any subscriptions."); //note empty string required for ui - so "$subscriptionsContent" not displayed String transformedResults = ""; if (StringUtils.isNotBlank(rawResults)) { transformedResults = searchResultConverter.convertSubscriptionSearchResult(rawResults, subResultsHtmlXsltParamMap); logger.info("Subscription Results HTML:\n" + transformedResults); } model.put("subscriptionsContent", transformedResults); model.put("informationMessages", informationMessage); return "subscriptions/_subscriptionResults"; } @RequestMapping(value = "filter", method = RequestMethod.POST) public String filter( @ModelAttribute("subscriptionFilterCommand") SubscriptionFilterCommand subscriptionFilterCommand, BindingResult errors, Map<String, Object> model) { String subscriptionStatus = subscriptionFilterCommand.getSubscriptionStatus(); logger.info("inside filter() for status: " + subscriptionStatus); String filterInput; //we do not wish to re-filter on filtered results - we always filter on results from a non-filtered search if (userSession.getSavedMostRecentSubscriptionSearchResult() == null) { userSession.setSavedMostRecentSubscriptionSearchResult( userSession.getMostRecentSubscriptionSearchResult()); filterInput = userSession.getMostRecentSubscriptionSearchResult(); } else { filterInput = userSession.getSavedMostRecentSubscriptionSearchResult(); } // filter xml with parameters passed in subscriptionFilterCommand.setCurrentDate(new Date()); String sValidationDueWarningDays = subscriptionFilterProperties.get("validationDueWarningDays"); int iValidationDueWarningDays = Integer.parseInt(sValidationDueWarningDays); subscriptionFilterCommand.setValidationDueWarningDays(iValidationDueWarningDays); logger.info("Using subscriptionFilterCommand: " + subscriptionFilterCommand); logger.info("\n * filterInput = \n" + filterInput); String sFilteredSubResults = searchResultConverter.filterXml(filterInput, subscriptionFilterCommand); //saving filtered results allows pagination to function: userSession.setMostRecentSearchResult(sFilteredSubResults); logger.info("Filtered Result: \n" + sFilteredSubResults); //transform the filtered xml results into html Map<String, Object> subResultsHtmlXsltParamMap = getParams(0, null, null); subResultsHtmlXsltParamMap.put("messageIfNoResults", "No " + subscriptionStatus + " subscriptions"); String htmlResult = ""; if (StringUtils.isNotBlank(sFilteredSubResults)) { htmlResult = searchResultConverter.convertSubscriptionSearchResult(sFilteredSubResults, subResultsHtmlXsltParamMap); } logger.info("Subscriptions Transformed Html:\n" + htmlResult); //put it in the model model.put("subscriptionsContent", htmlResult); //empty string(not null) prevents variable being displayed in ui html model.put("informationMessages", ""); return "subscriptions/_subscriptionResults"; } @RequestMapping(value = "clearFilter", method = RequestMethod.POST) public String clearFilter(Map<String, Object> model) { //reset the mostRecentSearchResult. if (userSession.getSavedMostRecentSubscriptionSearchResult() != null) { userSession.setMostRecentSubscriptionSearchResult( userSession.getSavedMostRecentSubscriptionSearchResult()); } Map<String, Object> subResultsHtmlXsltParamMap = getParams(0, null, null); String htmlResult = searchResultConverter.convertSubscriptionSearchResult( userSession.getMostRecentSubscriptionSearchResult(), subResultsHtmlXsltParamMap); //put it in the model model.put("subscriptionsContent", htmlResult); return "subscriptions/_subscriptionResults"; } /** * Intended to just be used for returning the modal contents to be * displayed for adding a subscription. Another method calls the service * to create the subscription */ @RequestMapping(value = "addSubscription", method = RequestMethod.POST) public String getAddSubscriptionModal(HttpServletRequest request, Map<String, Object> model) throws Exception { Subscription subscription = new Subscription(); // if there is only one real subscription type option, make it selected Map<String, String> subTypeMap = getSubscriptionTypeValueToLabelMap(); // size 2 means only drop down label and 1 real value if (subTypeMap.size() == 2) { for (String subType : subTypeMap.keySet()) { // ignoring empty requires dropdown label "sub type" have a value of empty string // so it will be ignored if (StringUtils.isNotBlank(subType)) { subscription.setSubscriptionType(subType); } } } model.put("subscription", subscription); logger.info("inside addSubscription()"); return "subscriptions/addSubscriptionDialog/_addSubscriptionModal"; } /** * Gets person original name and alternate(alias) names corresponding to * the state id(sid) in the provided request object * * Two-step process uses search service with sid to get system id * which is passed into the detail service */ @RequestMapping(value = "personNames", method = RequestMethod.GET) public @ResponseBody String getPersonNames(HttpServletRequest request, @ModelAttribute("detailsRequest") DetailsRequest detailsRequest, Map<String, Object> model) { String rNamesJsonArray = null; String personSid = detailsRequest.getIdentificationID(); String systemId = null; if (StringUtils.isNotBlank(personSid)) { systemId = getSystemIdFromPersonSID(request, detailsRequest); } if (StringUtils.isNotBlank(systemId)) { logger.info("using systemId: " + systemId); Document rapSheetDoc = processDetailQueryCriminalHistory(request, systemId); loadChDataFromRapsheet(rapSheetDoc, model); // consider making UI retrieve names from subscription pojo, since ui already // retrieves dob and fbi from sub. pojo rNamesJsonArray = prepareNamesFromRapSheetParsing(rapSheetDoc, model); } return rNamesJsonArray; } private Date parseRapsheetDate(String rapSheetDate) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date dobDate = null; try { dobDate = sdf.parse(rapSheetDate); } catch (ParseException e) { logger.severe("Couldn't parse date: " + rapSheetDate); e.printStackTrace(); } return dobDate; } private void loadChDataFromRapsheet(Document rapSheetDoc, Map<String, Object> model) { Subscription subscription = (Subscription) model.get("subscription"); logger.info("\n\n\n * * * * \n Subscription before loading CH data * * * * \n " + subscription + "\n\n\n"); String dobString = getDOBFromRapsheet(rapSheetDoc); Date dobDate = parseRapsheetDate(dobString); subscription.setDateOfBirth(dobDate); String fbiId = getFbiIdFromRapsheet(rapSheetDoc); subscription.setFbiId(fbiId); logger.info( "\n\n\n * * * * * \n\n Populated Subscription from Rapsheet \n " + subscription + "* * * * * \n"); // see if this is needed, because we already modified the object which is pass-by-reference model.put("subscription", subscription); } private String prepareNamesFromRapSheetParsing(Document rapSheetDoc, Map<String, Object> model) { String rNamesJsonArray = null; SubscribedPersonNames subscribedPersonNames = null; if (rapSheetDoc != null) { try { subscribedPersonNames = getAllPersonNamesFromRapsheet(rapSheetDoc); } catch (Exception e) { logger.severe("Exception getting names from rapsheet \n" + e); } } if (subscribedPersonNames != null) { List<String> allNamesList = new ArrayList<String>(); allNamesList.add(subscribedPersonNames.getOriginalName()); allNamesList.addAll(subscribedPersonNames.getAlternateNamesList()); JSONArray namesJsonArray = new JSONArray(allNamesList); rNamesJsonArray = namesJsonArray == null ? null : namesJsonArray.toString(); model.put("originalName", subscribedPersonNames.getOriginalName()); logger.info("returning all names: \n " + rNamesJsonArray + ", with original name: " + subscribedPersonNames.getOriginalName()); } return rNamesJsonArray; } @RequestMapping(value = "arrestForm", method = RequestMethod.POST) public String getArrestForm(HttpServletRequest request, Map<String, Object> model) throws Exception { logger.info("inside arrestForm()"); Subscription subscription = new Subscription(); initDatesForAddArrestForm(subscription, model); // pre-populate an email field on the form w/email from saml token String sEmail = userSession.getUserLogonInfo().emailAddress; if (StringUtils.isNotBlank(sEmail)) { subscription.getEmailList().add(sEmail); } String purposeSelection = subscriptionDefaultsMap.get("purpose"); if (StringUtils.isNotEmpty(purposeSelection)) { subscription.setSubscriptionPurpose(purposeSelection); } model.put("subscription", subscription); return "subscriptions/addSubscriptionDialog/_arrestForm"; } /** * note: uses pass-by-reference to modify subscription parameter * * pre-populate the subscription start date as a convenience to the user * this will be displayed on the modal */ private void initDatesForAddArrestForm(Subscription subscription, Map<String, Object> model) { SubscriptionStartDateStrategy startDateStrategy = subscriptionStartDateStrategyMap .get(ARREST_TOPIC_SUB_TYPE); Date defaultSubStartDate = startDateStrategy.getDefaultValue(); boolean isStartDateEditable = startDateStrategy.isEditable(); subscription.setSubscriptionStartDate(defaultSubStartDate); model.put("isStartDateEditable", isStartDateEditable); SubscriptionEndDateStrategy endDateStrategy = subscriptionEndDateStrategyMap.get(ARREST_TOPIC_SUB_TYPE); Date defaultSubEndDate = endDateStrategy.getDefaultValue(); boolean isEndDateEditable = endDateStrategy.isEditable(); subscription.setSubscriptionEndDate(defaultSubEndDate); model.put("isEndDateEditable", isEndDateEditable); } private void initDatesForEditArrestForm(Map<String, Object> model) { SubscriptionStartDateStrategy arrestEditSubStartDateStrategy = editSubscriptionStartDateStrategyMap .get(ARREST_TOPIC_SUB_TYPE); boolean isStartDateEditable = arrestEditSubStartDateStrategy.isEditable(); model.put("isStartDateEditable", isStartDateEditable); } private void initDatesForAddIncidentForm(Subscription subscription, Map<String, Object> model) { // START date SubscriptionStartDateStrategy startDateStrategy = subscriptionStartDateStrategyMap .get(INCIDENT_TOPIC_SUB_TYPE); Date defaultStartDate = startDateStrategy.getDefaultValue(); boolean isStartDateEditable = startDateStrategy.isEditable(); subscription.setSubscriptionStartDate(defaultStartDate); model.put("isStartDateEditable", isStartDateEditable); //END date SubscriptionEndDateStrategy endDateStrategy = subscriptionEndDateStrategyMap.get(INCIDENT_TOPIC_SUB_TYPE); Date defaultEndDate = endDateStrategy.getDefaultValue(); boolean isEndDateEditable = endDateStrategy.isEditable(); subscription.setSubscriptionEndDate(defaultEndDate); model.put("isEndDateEditable", isEndDateEditable); } private void initDatesForEditIncidentForm(Map<String, Object> model) { SubscriptionStartDateStrategy editIncidentSubStartDateStrategy = editSubscriptionStartDateStrategyMap .get(INCIDENT_TOPIC_SUB_TYPE); boolean isStartDateEditable = editIncidentSubStartDateStrategy.isEditable(); model.put("isStartDateEditable", isStartDateEditable); } private void initDatesForAddChCycleForm(Subscription subscription, Map<String, Object> model) { // START date SubscriptionStartDateStrategy startDateStrategy = subscriptionStartDateStrategyMap .get(CHCYCLE_TOPIC_SUB_TYPE); Date defaultStartDate = startDateStrategy.getDefaultValue(); boolean isStartDateEditable = startDateStrategy.isEditable(); subscription.setSubscriptionStartDate(defaultStartDate); model.put("isStartDateEditable", isStartDateEditable); //END date SubscriptionEndDateStrategy endDateStrategy = subscriptionEndDateStrategyMap.get(CHCYCLE_TOPIC_SUB_TYPE); Date defaultEndDate = endDateStrategy.getDefaultValue(); boolean isEndDateEditable = endDateStrategy.isEditable(); subscription.setSubscriptionEndDate(defaultEndDate); model.put("isEndDateEditable", isEndDateEditable); } private void initDatesForEditChCycleForm(Map<String, Object> model) { SubscriptionStartDateStrategy editIncidentSubStartDateStrategy = editSubscriptionStartDateStrategyMap .get(CHCYCLE_TOPIC_SUB_TYPE); boolean isStartDateEditable = editIncidentSubStartDateStrategy.isEditable(); model.put("isStartDateEditable", isStartDateEditable); } @RequestMapping(value = "incidentForm", method = RequestMethod.POST) public String getIncidentForm(HttpServletRequest request, Map<String, Object> model) throws Exception { logger.info("inside incidentForm()"); Subscription subscription = new Subscription(); initDatesForAddIncidentForm(subscription, model); String sEmail = userSession.getUserLogonInfo().emailAddress; if (StringUtils.isNotBlank(sEmail)) { subscription.getEmailList().add(sEmail); } model.put("subscription", subscription); return "subscriptions/addSubscriptionDialog/_incidentForm"; } @RequestMapping(value = "chCycleForm", method = RequestMethod.POST) public String getChCycleForm(HttpServletRequest request, Map<String, Object> model) throws Exception { logger.info("inside getChCycleForm()"); Subscription subscription = new Subscription(); initDatesForAddChCycleForm(subscription, model); String sEmail = userSession.getUserLogonInfo().emailAddress; if (StringUtils.isNotBlank(sEmail)) { subscription.getEmailList().add(sEmail); } model.put("subscription", subscription); return "subscriptions/addSubscriptionDialog/_chCycleForm"; } private void validateSubscription(Subscription subscription, BindingResult errors) { logger.info("subscription: \n" + subscription); if (ARREST_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { arrestSubscriptionAddValidator.validate(subscription, errors); } else if (INCIDENT_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { incidentSubscriptionAddValidator.validate(subscription, errors); } else if (CHCYCLE_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { chCycleSubscriptionValidator.validate(subscription, errors); } } /** * @return * json array string of errors if any. These can be used by the UI to display to the user */ @RequestMapping(value = "saveSubscription", method = RequestMethod.GET) public @ResponseBody String saveSubscription(HttpServletRequest request, @ModelAttribute("subscription") Subscription subscription, BindingResult errors) { logger.info("\n\n\n * * * * inside saveSubscription() * * * * *\n\n: " + subscription + "\n\n\n"); Element samlElement = samlService.getSamlAssertion(request); validateSubscription(subscription, errors); // retrieve any spring mvc validation errors from the controller List<String> errorsList = getValidationBindingErrorsList(errors); // if no spring mvc validation errors were found, call the subscribe operation and see if there are errors // from the notification broker response if (errorsList == null || errorsList.isEmpty()) { try { errorsList = processSubscribeOperation(subscription, samlElement); } catch (Exception e) { errorsList = Arrays.asList("An error occurred while processing subscription"); logger.severe("Failed processing subscription: " + e); } } List<String> subWarningsList = getSubscriptionWarnings(subscription); String errorMsgsWarnMsgsJson = getErrorsWarningsJson(errorsList, subWarningsList); logger.info("\n\n Returning errors/warnings json:\n\n" + errorMsgsWarnMsgsJson); return errorMsgsWarnMsgsJson; } List<String> getSubscriptionWarnings(Subscription subscription) { List<String> warningList = new ArrayList<String>(); if (ARREST_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { String fbiId = subscription.getFbiId(); if (StringUtils.isEmpty(fbiId)) { warningList.add("FBI ID missing. Subscription with the FBI is pending."); } } return warningList; } String getErrorsWarningsJson(List<String> errorsList, List<String> warningsList) { JSONObject errorsWarningsArraysJson = new JSONObject(); for (String error : errorsList) { errorsWarningsArraysJson.append("errors", error); } for (String warning : warningsList) { errorsWarningsArraysJson.append("warnings", warning); } String sErrWarnJson = errorsWarningsArraysJson.toString(); return sErrWarnJson; } /** * @return * json errors array (if any) * * @throws Exception * if no response received from subscribe operation */ private List<String> processSubscribeOperation(Subscription subscription, Element samlElement) throws Exception { if (subscription == null) { throw new Exception("subscription was null"); } logger.info("Calling subscribe operation..."); SubscriptionInterface subscribeBean = subConfig.getSubscriptionSubscribeBean(); FaultableSoapResponse faultableSoapResponse = subscribeBean.subscribe(subscription, getFederatedQueryId(), samlElement); logger.info("Subscribe operation returned faultableSoapResponse: " + faultableSoapResponse); List<String> subRespErrorsList = null; if (faultableSoapResponse != null) { subRespErrorsList = getErrorListFromSubscriptionResponse(faultableSoapResponse); } else { throw new Exception( "FaultableSoapResponse was null(got no response from subscribe operation), which is required"); } return subRespErrorsList; } /** * note default visibility so it can be unit-tested */ List<String> getErrorListFromSubscriptionResponse(FaultableSoapResponse faultableSoapResponse) throws Exception { if (faultableSoapResponse == null) { throw new Exception("FaultableSoapResponse was null"); } List<String> errorsList = null; Document subResponseDoc = getSubscriptionResponseDoc(faultableSoapResponse); if (subResponseDoc != null) { errorsList = getErrorsFromSubscriptionResponse(subResponseDoc); } else { errorsList = Arrays.asList("Did not receive subscription confirmation"); } return errorsList; } private Document getSubscriptionResponseDoc(FaultableSoapResponse faultableSoapResponse) throws Exception { if (faultableSoapResponse == null) { throw new Exception("Cannot get Document from null " + FaultableSoapResponse.class.getName()); } String sSoapEnvelope = faultableSoapResponse.getSoapResponse(); if (StringUtils.isBlank(sSoapEnvelope)) { throw new Exception("soap envelope was blank in the FaultableSoapResponse"); } Document soapEnvDoc = getDocBuilder().parse(new InputSource(new StringReader(sSoapEnvelope))); if (soapEnvDoc == null) { throw new Exception("soapEnvDoc Document could not be parsed"); } Document subResponseDoc = getSubscriptionResponseDocFromSoapEnvDoc(soapEnvDoc); if (subResponseDoc == null) { throw new Exception("Could not get subscription response document from soap envelope document"); } return subResponseDoc; } private Document getSubscriptionResponseDocFromSoapEnvDoc(Document soapEnvDoc) throws Exception { if (soapEnvDoc == null) { throw new Exception("Cannot get subscription response Document from null soap envelope document"); } Document rDocument = null; Node rootSubRespNode = null; if (SubscriptionResponseProcessor.isSubscriptionSuccessResponse(soapEnvDoc)) { rootSubRespNode = XmlUtils.xPathNodeSearch(soapEnvDoc, "//b-2:SubscribeResponse"); } else if (SubscriptionResponseProcessor.isUnsubscriptionAccessDenialResponse(soapEnvDoc)) { rootSubRespNode = XmlUtils.xPathNodeSearch(soapEnvDoc, "//b-2:UnableToDestroySubscriptionFault"); } else if (SubscriptionResponseProcessor.isSubscriptionFaultResponse(soapEnvDoc)) { rootSubRespNode = XmlUtils.xPathNodeSearch(soapEnvDoc, "//b-2:SubscribeCreationFailedFault"); } else { throw new Exception("Unknown Subscription Type"); } if (rootSubRespNode != null) { rDocument = getDocBuilder().newDocument(); Node importedNode = rDocument.importNode(rootSubRespNode, true); rDocument.appendChild(importedNode); } else { throw new Exception("Could not recognize subscription response"); } return rDocument; } private List<String> getErrorsFromSubscriptionResponse(Document subResponseDoc) throws Exception { if (subResponseDoc == null) { throw new Exception("subResponseDoc was null"); } SubscriptionResponseProcessor subResponseProcessor = new SubscriptionResponseProcessor(); List<SubscriptionResponse> subResponseList = subResponseProcessor.processResponse(subResponseDoc); if (subResponseList == null) { throw new Exception("Could not parse responses from response xml document"); } List<String> responseErrorList = new ArrayList<String>(); for (SubscriptionResponse iSubResponse : subResponseList) { SubscriptionResponseType iResponseType = iSubResponse.getResponseType(); if (SubscriptionResponseType.SUBSCRIPTION_SUCCESS != iResponseType) { String sError = getErrorFromResponse(iSubResponse); if (StringUtils.isEmpty(sError)) { throw new Exception("Couldn't get error from invalid response"); } responseErrorList.add(sError); logger.info("\n Parsed/received error: " + sError); } } return responseErrorList; } private String getErrorFromResponse(SubscriptionResponse subResponse) throws Exception { if (subResponse == null) { throw new Exception("Can't get error from null subscription response"); } String rErrorMsg = null; SubscriptionResponseType responseType = subResponse.getResponseType(); if (SubscriptionResponseType.SUBSCRIPTION_ACCESS_DENIAL == responseType) { SubscriptionAccessDenialResponse subAccessDenyResp = (SubscriptionAccessDenialResponse) subResponse; rErrorMsg = "Access Denied: \n"; rErrorMsg += subAccessDenyResp.getAccessDenyingReason() + "\n"; rErrorMsg += subAccessDenyResp.getAccessDenyingSystemName(); } else if (SubscriptionResponseType.SUBSCRIPTION_INVALID_EMAIL == responseType) { SubscriptionInvalidEmailResponse subInvalidEmailResp = (SubscriptionInvalidEmailResponse) subResponse; List<String> invalidEmailList = subInvalidEmailResp.getInvalidEmailList(); if (invalidEmailList == null || invalidEmailList.isEmpty()) { logger.warning("Determined Invalid email, but received no email address values"); } rErrorMsg = "Invalid Email(s): "; for (String iInvalidEmail : invalidEmailList) { rErrorMsg += iInvalidEmail + " "; } rErrorMsg = rErrorMsg.trim(); } else if (SubscriptionResponseType.SUBSCRIPTION_INVALID_TOKEN == responseType) { SubscriptionInvalidSecurityTokenResponse invalidTknResp = (SubscriptionInvalidSecurityTokenResponse) subResponse; rErrorMsg = "Invalid Security Token: \n"; rErrorMsg += invalidTknResp.getInvalidSecurityTokenDescription(); } else if (SubscriptionResponseType.SUBSCRIPTION_REQUEST_ERROR == responseType) { SubscriptionRequestErrorResponse invalidReqResp = (SubscriptionRequestErrorResponse) subResponse; rErrorMsg = "Invalid Request: \n"; rErrorMsg += invalidReqResp.getRequestErrorSystemName() + "\n"; rErrorMsg += invalidReqResp.getRequestErrorTxt(); } else if (SubscriptionResponseType.UNSUBSCRIPTION_ACCESS_DENIAL == responseType) { UnsubscriptionAccessDenialResponse unsubAcsDenialResp = (UnsubscriptionAccessDenialResponse) subResponse; rErrorMsg = "Access denied for unsubscription: \n"; rErrorMsg += unsubAcsDenialResp.getAccessDenyingSystemName() + "\n"; rErrorMsg += unsubAcsDenialResp.getAccessDenyingReason(); } else if (SubscriptionResponseType.SUBSCRIPTION_SUCCESS == responseType) { rErrorMsg = ""; logger.warning("Attempt was made to get subscription response error type for a scenario where the " + "subscription response was actually 'success'"); } else { throw new Exception("Subscription response type unrecognized"); } return rErrorMsg; } /** * Note: catches exceptions and sets model boolean to false to allow UI layer to display * an error. * * TODO maybe use spring binding to store the error instead of putting it in the regular model map * * @param identificationID * subscription id * @param topic * used to display appropriate form on the edit modal view */ @RequestMapping(value = "editSubscription", method = RequestMethod.GET) public String getSubscriptionEditModal(HttpServletRequest request, @RequestParam String identificationID, @RequestParam String topic, Map<String, Object> model) { try { //init success flag to true - allow processing below to set it to false if things go wrong model.put("initializationSucceeded", true); Document subQueryResponseDoc = runSubscriptionQueryForEditModal(identificationID, request); Subscription subscription = parseSubscriptionQueryResults(subQueryResponseDoc); List<String> allNamesList = null; if (ARREST_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { ChRapsheetData chRapsheetData = lookupChRapbackDataForArrestEdit(request, subscription, model); allNamesList = chRapsheetData.formattedAlternateNamesList; subscription.setFbiId(chRapsheetData.fbiNumber); Date rapSheetDob = parseRapsheetDate(chRapsheetData.personDob); subscription.setDateOfBirth(rapSheetDob); initDatesForEditArrestForm(model); } else if (INCIDENT_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { initDatesForEditIncidentForm(model); } else if (CHCYCLE_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { initDatesForEditChCycleForm(model); } if (allNamesList != null && !allNamesList.isEmpty()) { JSONArray namesJsonArray = new JSONArray(allNamesList); subscription.setPersonNamesJsonArray(namesJsonArray.toString()); } logger.info("Subscription Edit Request: " + subscription); model.put("subscription", subscription); } catch (Exception e) { model.put("initializationSucceeded", false); logger.info("initialization FAILED for identificationID=" + identificationID + ":\n" + e.toString()); } return "subscriptions/editSubscriptionDialog/_editSubscriptionModal"; } private class ChRapsheetData { List<String> formattedAlternateNamesList; SubscribedPersonNames subscribedPersonNames; String fbiNumber; String personDob; } private ChRapsheetData lookupChRapbackDataForArrestEdit(HttpServletRequest request, Subscription subscription, Map<String, Object> model) throws Exception { List<String> allNamesList = new ArrayList<String>(); ChRapsheetData chRapsheetData = getChRapbackData(request, subscription); SubscribedPersonNames subscribedNames = chRapsheetData.subscribedPersonNames; String originalName = subscribedNames == null ? null : subscribedNames.getOriginalName(); if (StringUtils.isNotBlank(originalName)) { allNamesList.add(originalName); } List<String> alternateNameList = subscribedNames == null ? null : subscribedNames.getAlternateNamesList(); if (alternateNameList != null && !alternateNameList.isEmpty()) { allNamesList.addAll(subscribedNames.getAlternateNamesList()); } if (allNamesList == null || allNamesList.isEmpty()) { model.put("initializationSucceeded", false); logger.severe("Failed to lookup names for arrest subscription"); } else { model.put("originalName", subscribedNames.getOriginalName()); } chRapsheetData.formattedAlternateNamesList = allNamesList; return chRapsheetData; } private Subscription parseSubscriptionQueryResults(Document subQueryResponseDoc) throws Exception { SubscriptionQueryResultsProcessor subQueryResultProcessor = new SubscriptionQueryResultsProcessor(); Subscription subscription = subQueryResultProcessor.parseSubscriptionQueryResults(subQueryResponseDoc); logger.info("Subscription Query Results: \n" + subscription.toString()); return subscription; } private Document runSubscriptionQueryForEditModal(String identificationID, HttpServletRequest request) throws Exception { Document subQueryResponseDoc = null; Element samlAssertion = samlService.getSamlAssertion(request); DetailsRequest subscriptionQueryRequest = new DetailsRequest(); subscriptionQueryRequest.setIdentificationID(identificationID); String subQueryResponse = null; subQueryResponse = subConfig.getSubscriptionQueryBean().invokeRequest(subscriptionQueryRequest, getFederatedQueryId(), samlAssertion); subQueryResponseDoc = getDocBuilder().parse(new InputSource(new StringReader(subQueryResponse))); logger.info("subQueryResponseDoc: \n"); XmlUtils.printNode(subQueryResponseDoc); return subQueryResponseDoc; } /** * @param idToTopicJsonProps * a json formatted string that's an object of name-value pairs where the * id is the name(key) and the topic is the value. ex: * {"62723":"{http://ojbc.org/wsn/topics}:person/arrest","62724":"{http://ojbc.org/wsn/topics}:person/arrest"} * * @return * the subscription results page(refreshed after validate) */ @RequestMapping(value = "validate", method = RequestMethod.POST) public String validate(HttpServletRequest request, @RequestParam String subIdToSubDataJson, Map<String, Object> model) { logger.info("Received subIdToSubDataJson: " + subIdToSubDataJson); Element samlAssertion = samlService.getSamlAssertion(request); processValidateSubscription(request, subIdToSubDataJson, model, samlAssertion); return "subscriptions/_subscriptionResults"; } private void processValidateSubscription(HttpServletRequest request, String subIdToSubDataJson, Map<String, Object> model, Element samlAssertion) { JSONObject subIdToSubDataJsonObjMap = new JSONObject(subIdToSubDataJson); String[] idJsonNames = JSONObject.getNames(subIdToSubDataJsonObjMap); // used to generated status message List<String> validatedIdList = new ArrayList<String>(); List<String> failedIdList = new ArrayList<String>(); // call the validate operation for each id/topic parameter for (String iSubId : idJsonNames) { JSONObject subIdToSubDataJsonObj = subIdToSubDataJsonObjMap.getJSONObject(iSubId); String iTopic = subIdToSubDataJsonObj.getString("topic"); String reasonCode = subIdToSubDataJsonObj.getString(""); try { FaultableSoapResponse faultableSoapResponse = subConfig.getSubscriptionValidationBean() .validate(iSubId, iTopic, reasonCode, getFederatedQueryId(), samlAssertion); //TODO see if we should check faultableSoapResponse exception attribute(if there is one) if (faultableSoapResponse == null) { failedIdList.add(iSubId); logger.severe("FAILED! to validate id: " + iSubId); continue; } boolean isValidated = getValidIndicatorFromValidateResponse(faultableSoapResponse); logger.info("isValidated: " + isValidated + " - for id: " + iSubId); if (isValidated) { validatedIdList.add(iSubId); } else { failedIdList.add(iSubId); } } catch (Exception e) { failedIdList.add(iSubId); logger.severe("FAILED! to validate id: " + iSubId + ", " + e); } } String operationResultMessage = getOperationResultStatusMessage(validatedIdList, failedIdList); refreshSubscriptionsContent(request, model, operationResultMessage); } boolean getValidIndicatorFromValidateResponse(FaultableSoapResponse faultableSoapResponse) throws Exception { boolean isValidated = false; if (faultableSoapResponse == null) { throw new Exception("FaultableSoapResponse param was null"); } Document soapBodyDoc = faultableSoapResponse.getSoapBodyDoc(); Document validateResponseDoc = null; Node rootValidRespNodeFromSoapEnvDoc = XmlUtils.xPathNodeSearch(soapBodyDoc, "//b-2:ValidateResponse"); if (rootValidRespNodeFromSoapEnvDoc != null) { validateResponseDoc = getDocBuilder().newDocument(); Node importedValidRespNodeFromSoapEnvDoc = validateResponseDoc .importNode(rootValidRespNodeFromSoapEnvDoc, true); validateResponseDoc.appendChild(importedValidRespNodeFromSoapEnvDoc); } else { throw new Exception("Could not recognize validate response message root node"); } SubscriptionValidationResponseProcessor validateResponseProcessor = new SubscriptionValidationResponseProcessor(); SubscriptionValidationResponse subValidResponse = validateResponseProcessor .processResponse(validateResponseDoc); isValidated = subValidResponse.isSubscriptionValidated(); return isValidated; } private String getOperationResultStatusMessage(List<String> succeededIdList, List<String> failedIdList) { String resultMessage = null; boolean hasSuccessfulIds = !succeededIdList.isEmpty(); boolean hasFailedIds = !failedIdList.isEmpty(); @SuppressWarnings("unused") String sSuccessIds = null; String sFailedIds = null; if (hasSuccessfulIds) { String[] aSuccessIds = succeededIdList.toArray(new String[] {}); sSuccessIds = Arrays.toString(aSuccessIds); } if (hasFailedIds) { String[] aFailedIds = failedIdList.toArray(new String[] {}); sFailedIds = Arrays.toString(aFailedIds); } if (hasFailedIds) { resultMessage = "Ids Failed: " + sFailedIds; } else { resultMessage = "Operation Successful"; } return resultMessage; } @RequestMapping(value = "unsubscribe", method = RequestMethod.GET) public String unsubscribe(HttpServletRequest request, @RequestParam String subIdToSubDataJson, Map<String, Object> model) { Element samlAssertion = samlService.getSamlAssertion(request); logger.info("* Unsubscribe using json param: " + subIdToSubDataJson); JSONObject subIdToSubDataJsonObj = new JSONObject(subIdToSubDataJson); String[] subIdJsonNames = JSONObject.getNames(subIdToSubDataJsonObj); // collections for status message List<String> successfulUnsubIdlist = new ArrayList<String>(); List<String> failedUnsubIdList = new ArrayList<String>(); for (String iId : subIdJsonNames) { JSONObject iSubDataJson = subIdToSubDataJsonObj.getJSONObject(iId); String iTopic = iSubDataJson.getString("topic"); String reasonCode = iSubDataJson.getString("reasonCode"); Unsubscription unsubscription = new Unsubscription(iId, iTopic, reasonCode); try { subConfig.getUnsubscriptionBean().unsubscribe(unsubscription, getFederatedQueryId(), samlAssertion); successfulUnsubIdlist.add(iId); } catch (Exception e) { failedUnsubIdList.add(iId); e.printStackTrace(); } } String operationStatusResultMsg = getOperationResultStatusMessage(successfulUnsubIdlist, failedUnsubIdList); refreshSubscriptionsContent(request, model, operationStatusResultMsg); return "subscriptions/_subscriptionResults"; } private void refreshSubscriptionsContent(HttpServletRequest request, Map<String, Object> model, String informationMessage) { Element samlElement = samlService.getSamlAssertion(request); String searchId = getFederatedQueryId(); String rawResults = null; try { rawResults = subConfig.getSubscriptionSearchBean().invokeSubscriptionSearchRequest(searchId, samlElement); } catch (Exception e) { e.printStackTrace(); logger.severe( "Failed retrieving subscriptions, ignoring informationMessage param: " + informationMessage); informationMessage = "Failed retrieving subscriptions"; } Map<String, Object> converterParamsMap = getParams(0, null, null); //note must default to empty string instead of null for ui to display nothing when desired instead // of having ui display "$subscriptionsContent" String transformedResults = ""; if (StringUtils.isNotBlank(rawResults)) { transformedResults = searchResultConverter.convertSubscriptionSearchResult(rawResults, converterParamsMap); } model.put("subscriptionsContent", transformedResults); model.put("informationMessages", informationMessage); } @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(DateTime.class, new DateTimePropertyEditor()); binder.registerCustomEditor(Date.class, new DateTimeJavaUtilPropertyEditor()); } @ModelAttribute("subscriptionTypeValueToLabelMap") public Map<String, String> getSubscriptionTypeValueToLabelMap() { return subscriptionTypeValueToLabelMap; } @ModelAttribute("subscriptionPurposeValueToLabelMap") public Map<String, String> getSubscriptionPurposeValueToLabelMap() { return subscriptionPurposeValueToLabelMap; } private ChRapsheetData getChRapbackData(HttpServletRequest request, Subscription subscription) throws Exception { DetailsRequest detailsRequestWithStateId = new DetailsRequest(); detailsRequestWithStateId.setIdentificationID(subscription.getStateId()); String crimHistSysIdFromPersonSid = getSystemIdFromPersonSID(request, detailsRequestWithStateId); if (StringUtils.isBlank(crimHistSysIdFromPersonSid)) { return null; } Document rapSheetDoc = processDetailQueryCriminalHistory(request, crimHistSysIdFromPersonSid); logger.info("Rapsheet doc for alt names: \n"); XmlUtils.printNode(rapSheetDoc); SubscribedPersonNames subscribedPersonNames = getAllPersonNamesFromRapsheet(rapSheetDoc); logger.info("Subscription person names: \n" + subscribedPersonNames.getOriginalName() + " + " + Arrays.toString(subscribedPersonNames.getAlternateNamesList().toArray())); ChRapsheetData chRapsheetData = new ChRapsheetData(); chRapsheetData.subscribedPersonNames = subscribedPersonNames; chRapsheetData.fbiNumber = getFbiIdFromRapsheet(rapSheetDoc); chRapsheetData.personDob = getDOBFromRapsheet(rapSheetDoc); return chRapsheetData; } private Map<String, Object> getParams(int start, String purpose, String onBehalfOf) { Map<String, Object> params = new HashMap<String, Object>(); params.put("purpose", purpose); params.put("onBehalfOf", onBehalfOf); params.put("validateSubscriptionButton", validateSubscriptionButton); return params; } // note system id is used by the broker intermediary to recognize that this is // an edit. The system id is not set for the add operation @RequestMapping(value = "updateSubscription", method = RequestMethod.GET) @ResponseStatus(value = HttpStatus.OK) public @ResponseBody String updateSubscription(HttpServletRequest request, @ModelAttribute("subscription") Subscription subscription, BindingResult errors, Map<String, Object> model) throws Exception { Element samlElement = samlService.getSamlAssertion(request); // get potential spring mvc controller validation errors from validating UI values validateSubscriptionUpdate(subscription, errors); List<String> errorsList = getValidationBindingErrorsList(errors); if (errorsList == null || errorsList.isEmpty()) { // get potential errors from processing subscribe operation errorsList = processSubscribeOperation(subscription, samlElement); } List<String> warningsList = getSubscriptionWarnings(subscription); String errorsWarningsJson = getErrorsWarningsJson(errorsList, warningsList); logger.info("\n\n updateSubscription(...) returning errors/warnings json: \n" + errorsWarningsJson); return errorsWarningsJson; } private void validateSubscriptionUpdate(Subscription subscription, BindingResult errorsBindingResult) { logger.info("sub Edit Request = \n" + subscription); if (ARREST_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { arrestSubscriptionEditValidator.validate(subscription, errorsBindingResult); } else if (INCIDENT_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { incidentSubscriptionEditValidator.validate(subscription, errorsBindingResult); } else if (CHCYCLE_TOPIC_SUB_TYPE.equals(subscription.getSubscriptionType())) { chCycleSubscriptionValidator.validate(subscription, errorsBindingResult); } } private List<String> getValidationBindingErrorsList(BindingResult errors) { List<String> errorMsgList = null; if (errors.hasErrors()) { List<ObjectError> bindingErrorsList = errors.getAllErrors(); errorMsgList = new ArrayList<String>(); for (ObjectError iObjError : bindingErrorsList) { String errorMsgCode = iObjError.getCode(); errorMsgList.add(errorMsgCode); } } return errorMsgList; } /** * @return systemId */ private String getSystemIdFromPersonSID(HttpServletRequest request, DetailsRequest detailsRequestWithSid) { logger.info("person sid: " + detailsRequestWithSid.getIdentificationID()); PersonSearchRequest personSearchRequest = new PersonSearchRequest(); personSearchRequest.setPersonSID(detailsRequestWithSid.getIdentificationID()); List<String> sourceSystemsList = Arrays.asList(OJBCWebServiceURIs.CRIMINAL_HISTORY_SEARCH); personSearchRequest.setSourceSystems(sourceSystemsList); Element samlAssertion = samlService.getSamlAssertion(request); String searchContent = null; try { searchContent = config.getPersonSearchBean().invokePersonSearchRequest(personSearchRequest, getFederatedQueryId(), samlAssertion); } catch (Exception e) { logger.severe("Exception thrown while invoking person search request:\n" + e); } Document personSearchResultDoc = null; if (StringUtils.isNotBlank(searchContent)) { try { DocumentBuilder docBuilder = getDocBuilder(); personSearchResultDoc = docBuilder.parse(new InputSource(new StringReader(searchContent))); } catch (Exception e) { logger.severe("Exception thrown while parsing search content Document:\n" + e); } } else { logger.severe("searchContent was blank"); } NodeList psrNodeList = null; if (personSearchResultDoc != null) { try { psrNodeList = XmlUtils.xPathNodeListSearch(personSearchResultDoc, "/emrm-exc:EntityMergeResultMessage/emrm-exc:EntityContainer/emrm-ext:Entity/psres:PersonSearchResult"); } catch (Exception e) { logger.severe("Exception thrown - getting nodes from PersonSearchResult:\n" + e); } } else { logger.severe("personSearchResultDoc was null"); } String systemId = null; if (psrNodeList != null && psrNodeList.getLength() == 1) { try { Node psrNode = psrNodeList.item(0); systemId = XmlUtils.xPathStringSearch(psrNode, "intel:SystemIdentifier/nc:IdentificationID"); } catch (Exception e) { logger.severe("Exception thrown referencing IdentificationID xpath: \n" + e); } } else { logger.severe("Search Results (SystemIdentifier/nc:IdentificationID) count != 1"); } return systemId; } /** * @return rap sheet */ private Document processDetailQueryCriminalHistory(HttpServletRequest request, String systemId) { DetailsRequest detailsRequest = new DetailsRequest(); detailsRequest.setIdentificationID(systemId); detailsRequest.setIdentificationSourceText(OJBCWebServiceURIs.CRIMINAL_HISTORY); Element samlAssertion = samlService.getSamlAssertion(request); String detailsContent = null; try { detailsContent = config.getDetailsQueryBean().invokeRequest(detailsRequest, getFederatedQueryId(), samlAssertion); } catch (Exception e) { logger.severe("Exception invoking details request:\n" + e); } if ("noResponse".equals(detailsContent)) { logger.severe("No response from Criminial History"); } Document detailsDoc = null; if (detailsContent != null) { try { detailsDoc = getDocBuilder().parse(new InputSource(new StringReader(detailsContent))); } catch (Exception e) { logger.severe("Exception parsing detailsContent:\n" + detailsContent + "\n, exception:\n" + e); } } return detailsDoc; } private String getFbiIdFromRapsheet(Document rapSheetDoc) { String fbiId = null; try { fbiId = XmlUtils.xPathStringSearch(rapSheetDoc, "/ch-doc:CriminalHistory/ch-ext:RapSheet/rap:RapSheetPerson/jxdm41:PersonAugmentation/jxdm41:PersonFBIIdentification/nc:IdentificationID"); } catch (Exception e) { logger.severe("Exception while getting fbi id from rapsheet: \n" + e); } return fbiId; } private String getDOBFromRapsheet(Document rapSheetDoc) { String dob = null; try { dob = XmlUtils.xPathStringSearch(rapSheetDoc, "/ch-doc:CriminalHistory/ch-ext:RapSheet/rap:Introduction/rap:RapSheetRequest/rap:RapSheetPerson/nc:PersonBirthDate/nc:Date"); } catch (Exception e) { logger.severe("Exception while getting dob from rapsheet \n" + e); } return dob; } SubscribedPersonNames getAllPersonNamesFromRapsheet(Document rapSheetDoc) throws Exception { SubscribedPersonNames rSubscribedPersonNames = new SubscribedPersonNames(); Node rapSheetNode = XmlUtils.xPathNodeSearch(rapSheetDoc, "/ch-doc:CriminalHistory/ch-ext:RapSheet"); Node pNameNode = XmlUtils.xPathNodeSearch(rapSheetNode, "rap:Introduction/rap:RapSheetRequest/rap:RapSheetPerson/nc:PersonName"); String personOrigFullName = getNameConcatinated(pNameNode); personOrigFullName = StringUtils.strip(personOrigFullName); if (StringUtils.isNotBlank(personOrigFullName)) { rSubscribedPersonNames.setOriginalName(personOrigFullName); } NodeList altNameNodeList = XmlUtils.xPathNodeListSearch(rapSheetNode, "rap:RapSheetPerson/nc:PersonAlternateName"); //process the alternate names for (int i = 0; i < altNameNodeList.getLength(); i++) { Node iAltNameNode = altNameNodeList.item(i); String fullNameContinated = getNameConcatinated(iAltNameNode); if (StringUtils.isNotBlank(fullNameContinated)) { rSubscribedPersonNames.getAlternateNamesList().add(fullNameContinated); } } return rSubscribedPersonNames; } String getNameConcatinated(Node nameNode) throws Exception { String fullName = ""; String fName = XmlUtils.xPathStringSearch(nameNode, "nc:PersonGivenName"); String mName = XmlUtils.xPathStringSearch(nameNode, "nc:PersonMiddleName"); String lName = XmlUtils.xPathStringSearch(nameNode, "nc:PersonSurName"); if (StringUtils.isNotBlank(fName)) { fullName += fName.trim(); } if (StringUtils.isNotBlank(mName)) { fullName += " " + mName.trim(); } if (StringUtils.isNotBlank(lName)) { fullName += " " + lName.trim(); } fullName = StringUtils.trim(fullName); return fullName; } static DocumentBuilder getDocBuilder() throws ParserConfigurationException { if (docBuilder == null) { DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); fact.setNamespaceAware(true); docBuilder = fact.newDocumentBuilder(); } return docBuilder; } }