Package com.krminc.phr.api.service

Source Code of com.krminc.phr.api.service.CareTakerUsersResource

/**
* Copyright (C) 2012 KRM Associates, Inc. healtheme@krminc.com
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.krminc.phr.api.service;

import com.krminc.phr.api.converter.UsersConverter;
import com.krminc.phr.api.service.util.ServiceUtils;
import com.krminc.phr.core.AppConfig;
import com.krminc.phr.core.UserConfig;
import com.krminc.phr.dao.PersistenceService;
import com.krminc.phr.domain.HealthRecord;
import com.krminc.phr.domain.HealthrecordRequest;
import com.krminc.phr.domain.User;
import com.sun.jersey.api.core.ResourceContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author cmccall
*/
public class CareTakerUsersResource {

    final Logger logger = LoggerFactory.getLogger(CareTakerUsersResource.class);

    /**
     *
     */
    @Context
    protected UriInfo uriInfo;
    /**
     *
     */
    @Context
    protected ResourceContext resourceContext;
    /**
     *
     */
    @Context
    protected SecurityContext securityContext;
    /**
     *
     */
    @Context
    protected transient HttpServletRequest servletRequest;

    private User localUser;

    /**
     *
     */
    public CareTakerUsersResource() {
    }


    /**
     * Get method for retrieving a collection of User instance in XML format.
     *
     * @param start
     * @param desc
     * @param max
     * @param orderBy
     * @param username
     * @param name
     * @return an instance of UsersConverter
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public UsersConverter get(
        @QueryParam("start") @DefaultValue("0") int start,
        @QueryParam("max") @DefaultValue("10") int max,
        @QueryParam("orderBy") @DefaultValue("name") String orderBy,
        @QueryParam("desc") @DefaultValue("0") int desc,
        @QueryParam("u") @DefaultValue("") String username,
        @QueryParam("e") @DefaultValue("") String name
    ) {
        PersistenceService persistenceSvc = PersistenceService.getInstance();
        try {
            persistenceSvc.beginTx();
            return new UsersConverter(
                    getEntities(start, max, orderBy, desc, username, name),
                    uriInfo.getAbsolutePath(),
                    Api.DEFAULT_EXPAND_LEVEL + 2); //expand deep to pull in healthrecordID
        } finally {
            persistenceSvc.close();
        }
    }

    /**
     * Returns a dynamic instance of UserResource used for entity navigation.
     *
     * @param id
     * @return an instance of UserResource
     */
    @Path("{userId}/")
    public UserResource getUserResource(@PathParam("userId") Long id) {
        UserResource resource = resourceContext.getResource(UserResource.class);
        resource.setId(id);
        return resource;
    }

    /**
     * Act as in logged in as user
     *
     * @param healthRecord
     * @return
     */
    @Path("access/{hrid}/")
    @GET
    public Response getAccess (@PathParam ("hrid") Long healthRecord) {
        if (healthRecord != null)
        {
            HttpSession session = servletRequest.getSession(true);
            session.setAttribute("healthRecordId", healthRecord);

            return Response.seeOther(uriInfo.getBaseUri().resolve("." + AppConfig.PATH_PATIENT_ROOT + "/" + healthRecord + "/dashboard")).build();
        } else {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }

    }

    /**
     * Remove a user from your care
     *
     * @param healthRecordIdToRemove
     * @return
     */
    @Path("remove/{hrid}/")
    @GET
    public JSONObject removeAccess (@PathParam ("hrid") Long healthRecordIdToRemove) {
        JSONObject jsonResult = new JSONObject();
        Boolean returnType = false;

        if (healthRecordIdToRemove != null)
        {

            PersistenceService persistenceSvc = PersistenceService.getInstance();

            try {
                EntityManager em = PersistenceService.getInstance().getEntityManager();
                User self = null;

                try {
                    persistenceSvc.beginTx();

                    //get user
                     self = getLocalUser(); //requires tx started

                     //find the correct hr
                     List<HealthRecord> healthRecords = self.getHealthRecords();
                     boolean shouldRemove = false;
                     HealthRecord toRemove = null;

                     for (HealthRecord hr : healthRecords) {
                         //prepare to remove link
                         if (healthRecordIdToRemove.compareTo(hr.getHealthRecordId()) == 0) {
                             toRemove = hr;
                             logger.debug("Ready to remove healthRecord {} from user {}", hr, self);
                             shouldRemove = true;
                         }
                     }

                     if (shouldRemove) {
                        healthRecords.remove(toRemove);
                        self.setHealthRecords(healthRecords);
                        em.flush();
                        persistenceSvc.commitTx();
                        returnType = true;
                     } else {
                         returnType = false;
                         persistenceSvc.rollbackTx();
                     }
                }
                catch (NoResultException ex) {
                    logger.error("Unable to find remove access for HRID: {}", healthRecordIdToRemove);
                    returnType = false;
                }

            }
            catch (Exception ex) {
                logger.error("removeAccess encountered exception: {}", ex);
                returnType = false;
            } finally {
                persistenceSvc.close();
            }
        } else {
            returnType = false;
        }

        try {
            if (returnType) {
                jsonResult.put("success", "Successfully removed patient from your care.");
            } else {
                jsonResult.put("error", "Unable to find that user. Please try again or contact an administrator if the problem persists.");
            }
        }
        catch (JSONException ex) {
            throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
        }
        return jsonResult;
    }

    /**
     * Ask for access to a patient's record
     *
     * @param username
     * @param email
     * @return
     */
    @Path("add/")
    @GET
    public JSONObject requestAccess(
        @QueryParam("u") @DefaultValue("") String username,
        @QueryParam("e") @DefaultValue("") String email
    ) {
        JSONObject jsonResult = new JSONObject();

        User patient = null;
        boolean error = false;
        if (!username.isEmpty()) {

            //query on username
            PersistenceService persistenceSvc = PersistenceService.getInstance();

            try {
                EntityManager em = PersistenceService.getInstance().getEntityManager();

                try {
                    persistenceSvc.beginTx();

                     patient = (User) em.createNamedQuery("User.findByUsername")
                        .setParameter("username", username)
                        .setMaxResults(1)
                        .getSingleResult();

                     persistenceSvc.commitTx();
                     logger.debug("Found User by username: {}", patient);
                }
                catch (NoResultException ex) {
                    logger.error("Unable to find User object for username: {}", username);
                    error = true;
                    jsonResult.put("error", "Unable to find user with that name.");
                }

            }
            catch (Exception ex) {
                logger.error("requestAccess encountered exception: {}", ex);
                error = true;
                try {
                    jsonResult.put("error", "Unable to find user with that name.");
                }
                catch (JSONException ex2) {
                    throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
                }
            } finally {
                persistenceSvc.close();
            }

        } else if (!email.isEmpty()) {

            //query on email
            PersistenceService persistenceSvc = PersistenceService.getInstance();

            try {
                EntityManager em = persistenceSvc.getEntityManager();

                try {
                    persistenceSvc.beginTx();

                     patient = (User) em.createNamedQuery("User.findByEmail")
                        .setParameter("email", email)
                        .setMaxResults(1)
                        .getSingleResult();

                     persistenceSvc.commitTx();
                     logger.debug("Found User by email: {}", patient);
                }
                catch (NoResultException ex) {
                    error = true;
                    logger.error("Unable to find User object for email: {}", email);
                    jsonResult.put("error", "Unable to find user with that email address.");
                }

            }
            catch (Exception ex) {
                error = true;
                logger.error("requestAccess encountered exception: {}", ex);
                try {
                    jsonResult.put("error", "Unable to find user with that email address.");
                }
                catch (JSONException ex2) {
                    throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
                }
            } finally {
                persistenceSvc.close();
            }

        } else {
            //no params -- cant do anything
            error = true;
            try {
                jsonResult.put("error", "Invalid search parameters.");
            }
            catch (JSONException ex) {
                throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
            }
        }
       
        //check that we don't already have an outstanding requests for this patient
        if (!error) { //dont bother if we've already got issues
            PersistenceService persistenceSvc = PersistenceService.getInstance();
            List<HealthrecordRequest> requests = null;
           
            try {
                EntityManager em = persistenceSvc.getEntityManager();
                try {
                    //grab all existing requests made by this caretaker
                    requests = (List<HealthrecordRequest>) em.createNamedQuery("HealthrecordRequest.findByUserIdRequestor")
                        .setParameter("userIdRequestor", getLocalUser().getUserId())
                        .getResultList();
                }
                catch (NoResultException ex) {
                    //ignore -- this is fine
                }

            }
            catch (Exception ex) {
                error = true;
                logger.error("requestAccess encountered exception: {}", ex);
                try {
                    jsonResult.put("error", "Unable to lookup current outstanding requests.");
                }
                catch (JSONException ex2) {
                    throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
                }
            } finally {
                persistenceSvc.close();
            }
           
            if ((requests != null) && (!error)) {
                for (HealthrecordRequest hrr : requests) {
                    //check each request's requested record id - does it match the current request attempt?
                    if (hrr.getRecIdRequested() == patient.getPrimaryHealthRecord().getHealthRecordId()) {
                        error = true;
                        try {
                            jsonResult.put("error", "A request for this patient's data already exists.");
                        }
                        catch (JSONException ex2) {
                            throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
                        }
                    }
                }
            }
        }
       
        //check patient is not already under our care
        if (!error) {
            for (User u : patient.getPrimaryHealthRecord().getUserList()) {
                if (u.getUserId().compareTo(getLocalUser().getUserId()) == 0) {
                    error = true;
                    try {
                        jsonResult.put("error", "Patient is already under your care.");
                    }
                    catch (JSONException ex) {
                        throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
                    }
                }
            }
        }

        //createDbRequest does the real work
        if (!error && createDbRequest(patient.getPrimaryHealthRecord().getHealthRecordId() )) {
            try {
                jsonResult.put("success", "Your request has been sent.");
            }
            catch (JSONException ex) {
                throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
            }
        }

        return jsonResult;
    }
   
    /**
     * List requests made by current user
     *
     * @return JSONArray of requests, or empty JSONArray
     */
    @Path("listRequests/")
    @GET
    public JSONArray listAccessRequests() {
        List<String> users = getUsernamesRequestedByUser();
       
        if ((users != null) && (! users.isEmpty() )) {
            return new JSONArray(users);
        } else {
            return new JSONArray();
        }
    }

    //helper method for requestAccess
    private boolean createDbRequest(Long requestedHealthrecordId) {
        HealthrecordRequest request = null;
        try {
            request = new HealthrecordRequest(requestedHealthrecordId.intValue(), getLocalUser().getUserId().intValue());
        }
        catch (Exception ex){
            throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
        }

        //persist request here via EM
        PersistenceService persistenceSvc = PersistenceService.getInstance();
        try {
            persistenceSvc.beginTx();
            EntityManager em = persistenceSvc.getEntityManager();
            request = em.merge(request);
            persistenceSvc.commitTx();
        } catch (Exception ex) {
            //ignored
        } finally {
            persistenceSvc.close();
        }

        return (request.getRequestId() > 0);
    }
   
    //helper method for listAccessRequests
    private List<String> getUsernamesRequestedByUser() {
        PersistenceService persistenceSvc = PersistenceService.getInstance();
        List<HealthrecordRequest> requests = null;
        List<String> usernames = new ArrayList<String>();
        try {
            EntityManager em = persistenceSvc.getEntityManager();
            requests = em.createNamedQuery("HealthrecordRequest.findByUserIdRequestor")
                    .setParameter("userIdRequestor", getLocalUser().getUserId())
                    .getResultList();
           
            for (HealthrecordRequest req : requests) {
                HealthRecord rec = (HealthRecord) em.createNamedQuery("HealthRecord.findByHealthRecordId")
                            .setParameter("healthRecordId", req.getRecIdRequested())
                            .getSingleResult();
                usernames.add(rec.getUser()
                                .getUsername()
                        ); //this is not optimized at all
            }
           
        } catch (Exception ex) {
            requests = null;
            logger.error("ex: {}", ex);
        } finally {
            persistenceSvc.close();
        }
       
        return usernames;
    }

    /**
     * Returns count of users belonging to the care taker
     *
     * @param username
     * @param name
     * @return
     */
    @Path("count/")
    @GET
    @Produces({ MediaType.APPLICATION_JSON })
    public JSONObject getCount(
        @QueryParam("u") @DefaultValue("") String username,
        @QueryParam("e") @DefaultValue("") String name
    ) {
//SELECT COUNT(DISTINCT u.user_id)
//FROM user_users_rec_healthrecord h JOIN user_users u ON h.user_id = u.user_id JOIN user_roles r ON UPPER(LTRIM(RTRIM(u.username))) = UPPER(LTRIM(RTRIM(r.username)))
//WHERE h.rec_id IN (SELECT rec_id FROM user_users_rec_healthrecord WHERE user_id = 3)
//AND r.role = "ROLE_PATIENT";

        StringBuilder query = new StringBuilder("SELECT COUNT(DISTINCT u.user_id) ");
        query.append("FROM user_users_rec_healthrecord h JOIN user_users u ON h.user_id = u.user_id ");
        query.append("JOIN user_roles r ON UPPER(LTRIM(RTRIM(u.username))) = UPPER(LTRIM(RTRIM(r.username))) ");
        query.append("WHERE h.rec_id IN (SELECT rec_id FROM user_users_rec_healthrecord WHERE user_id = ");

        Long result = 0L;
        Boolean hasFilterClause = true;

        if (this.getLocalUser() != null) {
            query.append("'" + this.getLocalUser().getUserId() + "' )");
        } else {
            throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
        }

        if (!username.isEmpty()){
            if (ServiceUtils.hasValidCharacters(username)) {
                if (!hasFilterClause){
                    query.append(" WHERE");
                    hasFilterClause = true;
                } else {
                    query.append(" AND");
                }
                username = "%" + username + "%";
                query.append(" u.username LIKE '" +username+"'");
            } else {
                throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
            }
        }

        if (!name.isEmpty()){
            if (ServiceUtils.hasValidCharacters(name)) {
                if (!hasFilterClause){
                    query.append(" WHERE");
                    hasFilterClause = true;
                } else {
                    query.append(" AND");
                }
                name = "%" + name + "%";
                query.append(" (u.first_name LIKE '" +name+"'");
                query.append(" OR");
                query.append(" u.last_name LIKE '" +name+"')");
            } else {
                throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
            }
        }

        //force only able to select PATIENT role users
        if (!hasFilterClause){
            query.append(" WHERE");
            hasFilterClause = true;
        } else {
            query.append(" AND");
        }
        query.append(" r.role IN ('"+UserConfig.ROLE_PATIENT+"')");

        PersistenceService persistenceSvc = PersistenceService.getInstance();
        try {
            persistenceSvc.beginTx();
            EntityManager em = persistenceSvc.getEntityManager();

//            logger.debug("Using query caretaker patient count query: {}", query);

            List resultD = (List)em.createNativeQuery(query.toString()).getSingleResult();
            result = (Long)resultD.get(0);
        } finally {
            persistenceSvc.close();
        }

        JSONObject jsonResult = new JSONObject();
        try {
            jsonResult.put("count", result);
        }
        catch (JSONException ex) {
            throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
        }
        return jsonResult;
    }

    /**
     * Returns all the entities associated with this care taker
     *
     * @param start
     * @param desc
     * @param max
     * @param username
     * @param orderBy
     * @param name
     * @return a collection of User instances
     */
    protected Collection<User> getEntities(
            int start, int max, String orderBy, int desc, String username, String name) {

//SELECT DISTINCT u.*
//FROM user_users_rec_healthrecord h JOIN user_users u ON h.user_id = u.user_id JOIN user_roles r ON UPPER(LTRIM(RTRIM(u.username))) = UPPER(LTRIM(RTRIM(r.username)))
//WHERE h.rec_id IN (SELECT rec_id FROM user_users_rec_healthrecord WHERE user_id = 3)
//AND r.role = "ROLE_PATIENT";

        StringBuilder query = new StringBuilder("SELECT DISTINCT u.* ");
        query.append("FROM user_users_rec_healthrecord h JOIN user_users u ON h.user_id = u.user_id ");
        query.append("JOIN user_roles r ON UPPER(LTRIM(RTRIM(u.username))) = UPPER(LTRIM(RTRIM(r.username))) ");
        query.append("WHERE h.rec_id IN (SELECT rec_id FROM user_users_rec_healthrecord WHERE user_id = ");

        Long result = 0L;
        Boolean hasFilterClause = true;

        if (this.getLocalUser() != null) {
            query.append("'" + this.getLocalUser().getUserId() + "' )");
        } else {
            throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
        }

        if(start<0) start=0;

        Boolean hasMax = true;
        if( max < 1 ){
            hasMax = false;
            start = 0;
        }

        if (!username.isEmpty()){
            if (ServiceUtils.hasValidCharacters(username)) {
                if (!hasFilterClause){
                    query.append(" WHERE");
                    hasFilterClause = true;
                } else {
                    query.append(" AND");
                }
                username = "%" + username + "%";
                query.append(" u.username LIKE '" +username+"'");
            } else {
                throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
            }
        }

        if (!name.isEmpty()){
            if (ServiceUtils.hasValidCharacters(name)) {
                if (!hasFilterClause){
                    query.append(" WHERE");
                    hasFilterClause = true;
                } else {
                    query.append(" AND");
                }
                name = "%" + name + "%";
                query.append(" (u.first_name LIKE '" +name+"'");
                query.append(" OR");
                query.append(" u.last_name LIKE '" +name+"')");
            } else {
                throw new WebApplicationException(Response.Status.PRECONDITION_FAILED);
            }
        }
       
        //force only able to select PATIENT role users
        if (!hasFilterClause){
            query.append(" WHERE");
            hasFilterClause = true;
        } else {
            query.append(" AND");
        }
        query.append(" r.role IN ('"+UserConfig.ROLE_PATIENT+"')");

        Boolean wasOrdered = false;
        if(orderBy.equalsIgnoreCase("username")){
            query.append(" ORDER BY u.username");
            wasOrdered = true;
        } else if(orderBy.equalsIgnoreCase("name")){
            query.append(" ORDER BY u.last_name, u.first_name, u.middle_name");
            wasOrdered = true;
        }

        if (wasOrdered) {
            if (desc>0) {
                query.append(" DESC");
            } else {
                query.append(" ASC");
            }
        }

//        logger.error("Using query caretaker patient lookup query: {}", query);

        EntityManager em = PersistenceService.getInstance().getEntityManager();

        Query filterQuery = em.createNativeQuery(query.toString(), User.class);

        if (hasMax) filterQuery.setMaxResults(max);

        List<User> users = (List<User>)filterQuery.setFirstResult(start).getResultList();
       
        return users;

    }

    private User getLocalUser() {
        if (localUser == null) {
            //get user id from db
            String localUserName = securityContext.getUserPrincipal().getName();

            PersistenceService persistenceSvc = PersistenceService.getInstance();

            if (localUserName != null && !localUserName.isEmpty()) {
                try {
                    EntityManager em = PersistenceService.getInstance().getEntityManager();

                    //persistenceSvc.beginTx(); //not needed -- called from transaction envt
                    try {
                         localUser = (User) em.createNamedQuery("User.findByUsername")
                            .setParameter("username", localUserName)
                            .setMaxResults(1)
                            .getSingleResult();

                         logger.debug("Found User by username: {}", localUser);
                    }
                    catch (NoResultException ex) {
                        localUser = null;
                        logger.debug("Unable to find User object for: {}", localUserName);
                    }

                }
                catch (Exception ex) {
                    localUser = null;
                    logger.error("getUserId encountered exception: {}", ex);
                } finally {
                    PersistenceService.getInstance().close();
                }

            } else {
                //no user in security context -- should not happen
                logger.error("Unable to find username from security context");
                localUser = null;
            }

            logger.debug("Successfully returning user: {}", localUser);

            return localUser;

        } else {
            return localUser;
        }
    }

}
TOP

Related Classes of com.krminc.phr.api.service.CareTakerUsersResource

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.