gov.medicaid.screening.dao.impl.NurseAnesthetistsLicenseDAOBean.java Source code

Java tutorial

Introduction

Here is the source code for gov.medicaid.screening.dao.impl.NurseAnesthetistsLicenseDAOBean.java

Source

/*
 * Copyright (C) 2012 TopCoder Inc., All Rights Reserved.
 */
package gov.medicaid.screening.dao.impl;

import gov.medicaid.entities.Address;
import gov.medicaid.entities.License;
import gov.medicaid.entities.LicenseStatus;
import gov.medicaid.entities.LicenseType;
import gov.medicaid.entities.NurseAnesthetistsSearchCriteria;
import gov.medicaid.entities.ProviderProfile;
import gov.medicaid.entities.User;
import gov.medicaid.screening.dao.NurseAnesthetistsLicenseDAO;
import gov.medicaid.screening.services.ErrorCode;
import gov.medicaid.screening.services.ParsingException;
import gov.medicaid.screening.services.ServiceException;
import gov.medicaid.screening.services.impl.LogUtil;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

/**
 * This defines the logic for scraping EPLS exclusion results.
 *
 * <p>
 * <code>Thread Safety</code> This is stateless EJB and is thread safe.
 * </p>
 *
 * @author argolite, j3_guile
 * @version 1.0
 */
@Stateless
@Local(NurseAnesthetistsLicenseDAO.class)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class NurseAnesthetistsLicenseDAOBean extends BaseDAO implements NurseAnesthetistsLicenseDAO {

    /**
     * Date format used by the source site.
     */
    private static final String DATE_FORMAT = "MM-dd-yyyy";

    /**
     * Default empty constructor.
     */
    public NurseAnesthetistsLicenseDAOBean() {
    }

    /**
     * Searches for Nurse Anesthetists license.
     *
     * @param criteria the search criteria
     * @return the matched profile
     * @throws IllegalArgumentException if the criteria is null
     * @throws IllegalArgumentException if the last 4 digits of the SSN is not provided
     * @throws IllegalArgumentException if the AANA number is not provided
     * @throws ServiceException for any other exceptions encountered
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public ProviderProfile search(NurseAnesthetistsSearchCriteria criteria) throws ServiceException {
        String signature = "NurseAnesthetistsLicenseDAOBean#search";
        LogUtil.traceEntry(getLog(), signature, new String[] { "criteria" }, new Object[] { criteria });

        if (criteria == null) {
            throw new IllegalArgumentException(ErrorCode.MITA10005.getDesc());
        }

        if (criteria.getSsn() == null || !criteria.getSsn().matches(".*[0-9]{4}$")) {
            throw new IllegalArgumentException(ErrorCode.MITA10025.getDesc());
        }

        if (criteria.getAanaNumber() <= 0) {
            throw new IllegalArgumentException(ErrorCode.MITA10026.getDesc());
        }

        try {
            ProviderProfile result = getProviderProfile(criteria);
            logSearchEntry(criteria);
            return LogUtil.traceExit(getLog(), signature, result);
        } catch (ServiceException e) {
            LogUtil.traceError(getLog(), signature, e);
            throw e;
        } catch (Throwable e) {
            LogUtil.traceError(getLog(), signature, e);
            throw new ServiceException(ErrorCode.MITA99999.getDesc(), e);
        }
    }

    /**
     * Performs the call to the source site, exact match is expected given the parameters.
     *
     * @param criteria the search criteria
     * @return the matched result, null if not found
     * @throws IOException if an I/O error is encountered
     * @throws URISyntaxException if the site URL cannot properly be created
     * @throws ServiceException for any other exceptions encountered
     */
    private ProviderProfile getProviderProfile(NurseAnesthetistsSearchCriteria criteria)
            throws ServiceException, IOException, URISyntaxException {
        DefaultHttpClient client = new DefaultHttpClient();
        client.setRedirectStrategy(new LaxRedirectStrategy());

        String searchURL = getSearchURL();
        HttpGet getSearch = new HttpGet(new URIBuilder(searchURL).build());
        HttpResponse response = client.execute(getSearch);
        verifyAndAuditCall(searchURL, response);

        Document page = Jsoup.parse(EntityUtils.toString(response.getEntity()));
        HttpPost search = new HttpPost(new URIBuilder(searchURL).build());

        String searchType = "Lookup Certification Status";

        String last4 = criteria.getSsn().substring(criteria.getSsn().length() - 4);
        HttpEntity entity = postForm(searchURL, client, search,
                new String[][] { { "__EVENTARGUMENT", "" }, { "__EVENTTARGET", "" },
                        { "__EVENTVALIDATION", page.select("input[name=__EVENTVALIDATION]").first().val() },
                        { "__VIEWSTATE", page.select("input[name=__VIEWSTATE]").first().val() },
                        { "ctl00$PageContent$CertRecert$btnLookup", searchType },
                        { "ctl00$PageContent$CertRecert$txtAANANumber", "" + criteria.getAanaNumber() },
                        { "ctl00$PageContent$CertRecert$txtSSNLast4", "" + last4 } },
                true);

        page = Jsoup.parse(EntityUtils.toString(entity));
        Elements message = page.select("#ctl00_PageContent_ucCredentialsControl_lblErrorMessage");
        if (message.size() > 0) {
            if (message.text().startsWith("No individual with a social security number")) {
                // no match, return null
                return null;
            }
        }

        if (criteria.isRecertification()) {
            searchType = "Lookup Recertification Status";
            entity = postForm(searchURL, client, search,
                    new String[][] { { "__EVENTARGUMENT", "" }, { "__EVENTTARGET", "" },
                            { "__EVENTVALIDATION", page.select("input[name=__EVENTVALIDATION]").first().val() },
                            { "__VIEWSTATE", page.select("input[name=__VIEWSTATE]").first().val() },
                            { "ctl00$PageContent$CertRecert$btnSwapDisplayMode", searchType } },
                    true);
            page = Jsoup.parse(EntityUtils.toString(entity));
        }
        return parseProvider(page);
    }

    /**
     * Parses the provider details from the response.
     *
     * @param page the response page
     * @return the parsed provider details
     * @throws ParsingException if the page is not of the expected format
     */
    private ProviderProfile parseProvider(Document page) throws ParsingException {
        ProviderProfile profile = new ProviderProfile();
        String fullName = page.select("#ctl00_PageContent_CertRecert_lblMemberName").text();
        if (Util.isBlank(fullName)) { // this should always be present
            throw new ParsingException(ErrorCode.MITA50002.getDesc());
        }
        profile.setUser(parseName(fullName));

        ArrayList<License> licenses = new ArrayList<License>();
        License license = new License();
        licenses.add(license);
        profile.setLicenses(licenses);

        String issueDate = page.select("#ctl00_PageContent_CertRecert_lblInitialCertificationDate").text();
        if (Util.isNotBlank(issueDate)) {
            license.setOriginalIssueDate(parseDate(issueDate, DATE_FORMAT));
        }
        String renewalDate = page.select("#ctl00_PageContent_CertRecert_lblRecertBeginDate").text();
        if (Util.isNotBlank(renewalDate)) {
            license.setRenewalDate(parseDate(renewalDate, DATE_FORMAT));
        }

        String renewalEndDate = page.select("#ctl00_PageContent_CertRecert_lblRecertEndDate").text();
        if (Util.isNotBlank(renewalEndDate)) {
            license.setRenewalDate(parseDate(renewalEndDate, DATE_FORMAT));
        }
        String status = page.select("#ctl00_PageContent_CertRecert_lblRecertStatus").text();
        if (Util.isNotBlank(status)) {
            LicenseStatus licenseStatus = new LicenseStatus();
            licenseStatus.setName(status);
            license.setStatus(licenseStatus);
        }

        String licenseName = page.select("#ctl00_PageContent_CertRecert_lblAnesthesiaProgramName").text();
        if (Util.isNotBlank(licenseName)) {
            LicenseType type = new LicenseType();
            type.setName(licenseName);
            license.setType(type);
        }

        String licenseNo = page.select("#ctl00_PageContent_CertRecert_lblAANANumber").text();
        license.setLicenseNumber(licenseNo);

        String address = page.select("#ctl00_PageContent_CertRecert_lblMemberResidence").text();
        if (Util.isNotBlank(address)) {
            List<Address> addresses = new ArrayList<Address>();
            addresses.add(parseAddress(address));
            profile.setAddresses(addresses);
        }

        return profile;
    }

    /**
     * Parse full address.
     *
     * @param fullAddress The full address.
     * @return the address object.
     */
    private static Address parseAddress(String fullAddress) {
        Address address = new Address();
        int citySeparator = fullAddress.indexOf(",");
        if (citySeparator > -1) {
            address.setCity(fullAddress.substring(0, citySeparator));
        }
        address.setZipcode(fullAddress.substring(fullAddress.lastIndexOf(" "), fullAddress.length()).trim());
        address.setState(fullAddress.substring(citySeparator + 1, fullAddress.lastIndexOf(" ")).trim());
        address.setCountry("US");
        return address;
    }

    /**
     * Parses the full name into a User object.
     *
     * @param fullName the full name displayed on the site
     * @return the parsed name
     */
    private User parseName(String fullName) {
        fullName = fullName.substring(0, fullName.indexOf(",")); // remove certificate title
        User user = new User();
        Stack<String> nameParts = new Stack<String>();
        for (String string : fullName.split(" ")) {
            nameParts.push(string);
        }
        user.setLastName(nameParts.pop());
        if (nameParts.size() > 1) {
            user.setMiddleName(nameParts.pop());
        }
        StringBuffer sb = new StringBuffer();
        while (!nameParts.isEmpty()) {
            sb.insert(0, nameParts.pop() + " ");
        }
        user.setFirstName(sb.toString().trim());
        return user;
    }
}