Package ke.go.moh.oec.mpi.list

Source Code of ke.go.moh.oec.mpi.list.PersonIdentifierList

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is OpenEMRConnect.
*
* The Initial Developer of the Original Code is International Training &
* Education Center for Health (I-TECH) <http://www.go2itech.org/>
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
package ke.go.moh.oec.mpi.list;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import ke.go.moh.oec.PersonIdentifier;
import ke.go.moh.oec.mpi.Sql;
import ke.go.moh.oec.mpi.ValueMap;

/**
* MPI Methods to operate on a list of person identifiers.
*
* @author Jim Grace
*/
public class PersonIdentifierList {

    private Connection conn;    // Connection for loading fingerprints
    private ResultSet rs;       // Result set for loading fingerprints
    private boolean rsNext;     // Is there a next record in the result set?
    private int personId;       // Remember current person ID.

    /**
     * Positions to the next person identifier record and gets the personId from that record.
     * This is encapsulated mainly to insure that rs.getInt() is only called once per record
     * for the person_id field. It turns out that this call is moderately CPU expensive
     * since it parses the database value into an integer every time. So we do this call
     * only once and save the integer result. We may then reference it more than once.
     */
    private void next() {
        try {
            rsNext = rs.next();
            if (rsNext) {
                personId = rs.getInt("person_id");
            }
        } catch (SQLException ex) {
            Logger.getLogger(PersonIdentifierList.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   
    /**
     * Starts loading person identifiers into memory.
     * <p>
     * For efficiency, person identifiers for all patients are loaded by a single query,
     * in order by personId. Then a merge sort on person identifiers is done between the
     * loaded person identifiers list and the loaded person list.
     */
    public void loadStart(int minPersonId, int maxPersonId) {
        conn = Sql.connect();
        String sql = "SELECT pi.person_id, pi.identifier, pi.identifier_type_id\n"
                + "FROM person_identifier pi\n"
                + "WHERE pi.person_id BETWEEN " + minPersonId + " AND " + maxPersonId + "\n"
                + "ORDER BY pi.person_id";
        rs = Sql.query(conn, sql, Level.FINEST);
        next();     // Position at the first result record.
    }

    /**
     * Loads the next person identifiers into memory matching the given personId.
     *
     * @param dbPersonId Database person_id value for person identifiers to load.
     * @return list of person identifiers for this person.
     */
    public List<PersonIdentifier> loadNext(int dbPersonId) {
        List<PersonIdentifier> personIdentifierList = null;
        try {
            // If we haven't yet reached the requested personId, skip over any
            // database records that come before that personId.
            while (rsNext && personId < dbPersonId) {
                next();
            }
            // While we are matching the requested personId, include any
            // person identifiers that match that Id.
            while (rsNext && personId == dbPersonId) {
                if (personIdentifierList == null) {
                    personIdentifierList = new ArrayList<PersonIdentifier>();
                }
                String idType = Integer.toString(rs.getInt("identifier_type_id"));
                PersonIdentifier.Type pit = (PersonIdentifier.Type) ValueMap.PERSON_IDENTIFIER_TYPE.getVal().get(idType);
                PersonIdentifier pi = new PersonIdentifier();
                pi.setIdentifier(rs.getString("identifier"));
                pi.setIdentifierType(pit);
                personIdentifierList.add(pi);
                next();
            }
        } catch (SQLException ex) {
            Logger.getLogger(FingerprintList.class.getName()).log(Level.SEVERE, null, ex);
        }
        return personIdentifierList;
    }

    /**
     * Ends loading fingerprints.
     * Releases any resources used.
     */
    public void loadEnd() {
        Sql.close(rs);
        Sql.close(conn);
    }

    /**
     * Updates the list of person identifiers for a given person.
     * <p>
     * The agent doing the updating may be concerned with only one or more types
     * of person identifiers. So the update that takes place depends on the type(s) of
     * identifiers supplied. For any type of identifier supplied in the update,
     * all existing identifiers of that type are removed, and the new identifier(s)
     * of that type are inserted.
     * <p>
     * If the client wishes to remove all identifiers of a certain type, it should
     * do an update with a null or empty identifier of that type. In this case,
     * all existing identifiers of that type will be removed, and the new
     * null or empty identifier will not be added.
     * <p>
     * If the client wishes to replace an identifier of type cccUniqueId or cccLocalId
     * for a particular clinic, the client should specify one or more IDs of that
     * type with the given 5-digit clinic code. Only old IDs with the same clinic id
     * will be replaced by the new identifier(s).
     * <p>
     * If the client wishes to remove an identifier of type cccUniqueId or cccLocalId
     * for a particular clinic, the client should specify an IDs of that
     * type with the given 5-digit clinic code, but with nothing following the clinic
     * code. Any existing identifiers of that type with that clinic code will be
     * removed, and no new clinic IDs of that type for that clinic will be added.
     *
     * @param conn database connection to use
     * @param personId database person.person_id primary key value
     * @param updateList list of PersonIdentifiers specified for update
     * @param piList existing list of PersonIdentifiers for the person
     * @return updated list of PersonIdentifiers for the person
     */
    public static List<PersonIdentifier> update(Connection conn, int personId, List<PersonIdentifier> updateList, List<PersonIdentifier> piList) {
        if (updateList != null && updateList.size() > 0) { // Do we have anything to update?
            List<PersonIdentifier> deleteList = new ArrayList<PersonIdentifier>(); // What person identifiers should we delete?
            List<PersonIdentifier> addList = new ArrayList<PersonIdentifier>(); // What person identifiers should we add?
            String sql;
            for (PersonIdentifier newP : updateList) { // Go through all the identifiers on the update list:
                PersonIdentifier.Type piType = newP.getIdentifierType();
                String id = newP.getIdentifier();
                String dbType = ValueMap.PERSON_IDENTIFIER_TYPE.getDb().get(piType);
                boolean idExists = false; // Does the new ID exist in the current list?
                if (piList != null) { // Might we have any existing identifiers to delete?
                    for (PersonIdentifier oldP : piList) {
                        if (oldP.getIdentifierType() == piType) {
                            String existingId = oldP.getIdentifier();
                            if (existingId.equals(id)) {
                                idExists = true; // Existing ID matches new ID -- don't need to delete or add.
                            } else if ((piType != PersonIdentifier.Type.cccLocalId && piType != PersonIdentifier.Type.cccUniqueId)
                                    || (id != null && id.substring(0, 5).equals(existingId.substring(0, 5)))) {
                                deleteList.add(oldP);
                            }
                        }
                    }
                }
                if (id != null && !id.isEmpty() && !idExists) { // If have a new identifier (and not already existing), then add it.
                    // Make sure we don't add a clinic ID of the form '12345' or '12345-'
                    // If this form is specified, it is a spacial request to delete any IDs from this clinic
                    // but to not add a new ID for this clinic. (See the JavaDoc for this method, above.)
                    if (!((piType == PersonIdentifier.Type.cccLocalId || piType == PersonIdentifier.Type.cccUniqueId)
                            && id.length() <= 6)) {
                        addList.add(newP);
                    }
                }
            }
            if (!deleteList.isEmpty()) { // Do we have any identifiers to delete from the database / remove from memory?
                for (PersonIdentifier pi : deleteList) {
                    String dbType = ValueMap.PERSON_IDENTIFIER_TYPE.getDb().get(pi.getIdentifierType());
                    sql = "DELETE FROM person_identifier "
                            + " WHERE person_id = " + personId
                            + " AND identifier_type_id = " + dbType
                            + " AND identifier = " + Sql.quote(pi.getIdentifier());
                    Sql.execute(conn, sql);
                }
                piList.removeAll(deleteList);
            }
            if (!addList.isEmpty()) { // Do we have anything to insert into the database / add to memory?
                for (PersonIdentifier pi : addList) {
                    String dbType = ValueMap.PERSON_IDENTIFIER_TYPE.getDb().get(pi.getIdentifierType());
                    sql = "INSERT INTO person_identifier (person_id, identifier_type_id, identifier) values ("
                            + personId + ", " + dbType + ", " + Sql.quote(pi.getIdentifier()) + ")";
                    Sql.execute(conn, sql);
                }
                if (piList == null) {
                    piList = new ArrayList<PersonIdentifier>();
                }
                piList.addAll(addList);
            }
        }
        return piList;
    }
}
TOP

Related Classes of ke.go.moh.oec.mpi.list.PersonIdentifierList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.