au.edu.anu.metadatastores.store.grants.GrantService.java Source code

Java tutorial

Introduction

Here is the source code for au.edu.anu.metadatastores.store.grants.GrantService.java

Source

/*******************************************************************************
 * Australian National University Metadata Stores
 * Copyright (C) 2013  The Australian National University
 * 
 * This file is part of Australian National University Metadata Stores.
 * 
 * Australian National University Metadata Stores is free software: you
 * can redistribute it and/or modify it under the terms of the GNU
 * General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/

package au.edu.anu.metadatastores.store.grants;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.edu.anu.metadatastores.datamodel.store.HistItemAttribute;
import au.edu.anu.metadatastores.datamodel.store.Item;
import au.edu.anu.metadatastores.datamodel.store.ItemAttribute;
import au.edu.anu.metadatastores.datamodel.store.ItemRelation;
import au.edu.anu.metadatastores.datamodel.store.ItemRelationId;
import au.edu.anu.metadatastores.datamodel.store.annotations.ItemTraitParser;
import au.edu.anu.metadatastores.datamodel.store.ext.StoreAttributes;
import au.edu.anu.metadatastores.services.ands.ANDSService;
import au.edu.anu.metadatastores.services.aries.ANUActivity;
import au.edu.anu.metadatastores.services.aries.AriesService;
import au.edu.anu.metadatastores.services.store.StoreHibernateUtil;
import au.edu.anu.metadatastores.store.misc.AbstractItemService;
import au.edu.anu.metadatastores.store.misc.Subject;
import au.edu.anu.metadatastores.store.people.Person;
import au.edu.anu.metadatastores.store.people.PersonItem;
import au.edu.anu.metadatastores.store.people.PersonService;
import au.edu.anu.metadatastores.store.properties.StoreProperties;

/**
 * <p>GrantService<p>
 * 
 * <p>The Australian National University</p>
 * 
 * <p>Service class to retrieve and update grant information</p>
 * 
 * @author Genevieve Turner
 *
 */
public class GrantService extends AbstractItemService {
    static final Logger LOGGER = LoggerFactory.getLogger(GrantService.class);

    private static GrantService singleton_;
    private AriesService ariesService_ = AriesService.getSingleton();
    private PersonService personService_ = PersonService.getSingleton();
    private ANDSService andsService_ = ANDSService.getSingleton();

    private static final String ARC_FUNDS_PROVIDER = StoreProperties.getProperty("arc.grant.title");
    private static final String NHMRC_FUNDS_PROVIDER = StoreProperties.getProperty("nhmrc.grant.title");
    private static final String ARC_PREFIX = StoreProperties.getProperty("arc.prefix");
    private static final String NHMRC_PREFIX = StoreProperties.getProperty("nhmrc.prefix");

    /**
     * Main class to execute grants
     * 
     * @param args Arguments
     */
    public static void main(String[] args) {
        GrantService grantService = GrantService.getSingleton();
        for (int i = 0; i < args.length; i++) {
            System.out.println("Argument " + i + ": " + args[i]);
            if (args[i].startsWith("u") || args[i].startsWith("a") || args[i].startsWith("f")) {
                List<Grant> grants = grantService.fetchGrantsForPerson(args[i]);
                for (Grant grant : grants) {
                    grantService.saveGrant(grant);
                }
            }
        }
    }

    /**
     * Constructor
     */
    private GrantService() {

    }

    /**
     * Get the GrantService instance
     * 
     * @return  The GrantService
     */
    public static GrantService getSingleton() {
        if (singleton_ == null) {
            singleton_ = new GrantService();
        }
        return singleton_;
    }

    /**
     * Fetches grant information from the Aries Database
     * 
     * @param staffId The id of the staff member to find grants for
     * @return A list of grants associated with the given staff member
     */
    public List<Grant> fetchGrantsForPerson(String staffId) {
        ANUActivity[] activities = ariesService_.getContracts(staffId);

        List<Grant> grants = new ArrayList<Grant>();

        Grant grant = null;
        for (ANUActivity activity : activities) {
            grant = new Grant();
            grant.setContractCode(activity.getActivityId());
            grant.setTitle(activity.getActivityTitle());
            Person firstInvestigator = new Person();
            firstInvestigator.setExtId(activity.getFirstInvestigatorId());
            grant.setFirstInvestigator(firstInvestigator);
            Person person = null;
            List<Person> people = new ArrayList<Person>();
            for (String investigatorId : activity.getInvestigators()) {
                person = new Person();
                person.setExtId(investigatorId);
                people.add(person);
            }
            grant.setAssociatedPeople(people);
            grant.setStartDate(activity.getStartDate());
            grant.setEndDate(activity.getEndDate());
            grant.setStatus(activity.getStatus());
            grant.setFundsProvider(activity.getFundsProvider());
            grant.setReferenceNumber(activity.getSchemeReference());

            if (activity.getForSubject1() != null) {
                Subject subject = new Subject(activity.getForSubject1().getCode(),
                        activity.getForSubject1().getDescription(), activity.getForSubject1().getPercentage());
                grant.getAnzforSubjects().add(subject);
            }
            if (activity.getForSubject2() != null) {
                Subject subject = new Subject(activity.getForSubject2().getCode(),
                        activity.getForSubject2().getDescription(), activity.getForSubject2().getPercentage());
                grant.getAnzforSubjects().add(subject);
            }
            if (activity.getForSubject3() != null) {
                Subject subject = new Subject(activity.getForSubject3().getCode(),
                        activity.getForSubject3().getDescription(), activity.getForSubject3().getPercentage());
                grant.getAnzforSubjects().add(subject);
            }

            grant.setDescription(getDescription(grant));

            grants.add(grant);
        }

        return grants;
    }

    /**
     * Set the description.
     * 
     * The information for this field is retrieved from ANDS
     * 
     * @param grant The grant to retrieve the description for
     * @return The description
     */
    private String getDescription(Grant grant) {
        String description = null;
        if (grant.getFundsProvider() != null && grant.getFundsProvider().trim().length() > 0
                && grant.getReferenceNumber() != null && grant.getReferenceNumber().trim().length() > 0) {
            if (ARC_FUNDS_PROVIDER.equals(grant.getFundsProvider())) {
                String key = ARC_PREFIX + grant.getReferenceNumber();
                description = andsService_.getActivityDescription(key);
            } else if (NHMRC_FUNDS_PROVIDER.equals(grant.getFundsProvider())) {
                String key = NHMRC_PREFIX + grant.getReferenceNumber();
                description = andsService_.getActivityDescription(key);
            }
        }

        return description;
    }

    /**
     * Save the given grant and make the appropriate associations
     * 
     * @param grant The grant to save
     * @return The grant item that has been created/updated
     */
    public GrantItem saveGrant(Grant grant) {
        return saveGrant(grant, Boolean.FALSE);
    }

    /**
     * Save a list of grants
     * 
     * @param grants The grants to save
     * @return THe saved grant items
     */
    public List<GrantItem> saveGrants(List<Grant> grants) {
        List<GrantItem> grantItems = new ArrayList<GrantItem>();
        GrantItem grantItem = null;

        for (Grant grant : grants) {
            grantItem = saveGrant(grant);
            grantItems.add(grantItem);
        }

        return grantItems;
    }

    /**
     * Save the grant information
     * 
     * @param grant The grant to save
     * @param userUpdated Indicator of whether it is user updated or system updated
     * @return The GrantItem that has been created/updated
     */
    public GrantItem saveGrant(Grant grant, Boolean userUpdated) {
        Session session = StoreHibernateUtil.getSessionFactory().openSession();

        GrantItem item = null;
        try {
            session.enableFilter("attributes");
            session.beginTransaction();

            Query query = session.createQuery("from GrantItem where extId = :extId");
            query.setParameter("extId", grant.getContractCode());

            item = (GrantItem) query.uniqueResult();

            Date lastModified = new Date();
            ItemTraitParser parser = new ItemTraitParser();
            Item newItem = null;
            newItem = parser.getItem(grant, userUpdated, lastModified);

            if (item == null) {
                item = new GrantItem();
                if (newItem.getExtId() == null) {
                    return null;
                }
                item.setExtId(newItem.getExtId());
                session.save(item);
            }

            updateAttributesFromItem(item, newItem, session, lastModified);

            LOGGER.debug("Number of item attributes before: {}", item.getItemAttributes().size());

            associatePeople(item, grant, session);

            LOGGER.debug("Number of Item Attributes after: {}", item.getItemAttributes().size());

            item = (GrantItem) session.merge(item);
            session.getTransaction().commit();
        } catch (IllegalAccessException e) {
            LOGGER.error("Exception accessing field when trying to get a grant item", e);
        } catch (InvocationTargetException e) {
            LOGGER.error("Exception invoking method when trying to get a grant item", e);
        } catch (Exception e) {
            if (item == null) {
                LOGGER.error("Exception querying item", e);
            } else {
                LOGGER.error("Error Merging Item {}", item.getIid(), e);
                LOGGER.info("Error with item: {}, Title: {}, System: {}, Ext Id: {}", item.getIid(),
                        item.getTitle(), item.getExtSystem(), item.getExtId());
                for (ItemAttribute attr : item.getItemAttributes()) {
                    LOGGER.info("AID: {}, IID: {}, Type: {}, Value: {}", new Object[] { attr.getAid(),
                            attr.getItem().getIid(), attr.getAttrType(), attr.getAttrValue() });
                }
                for (HistItemAttribute attr : item.getHistItemAttributes()) {
                    LOGGER.info("AID: {}, Date: {}, Type: {}, Value: {}", new Object[] { attr.getId().getAid(),
                            attr.getId().getHistDatetime(), attr.getAttrType(), attr.getAttrValue() });
                }
            }
        } finally {
            session.close();
        }

        return item;
    }

    /**
     * Add the people involved with the grant
     * 
     * @param item The grant item to add people to
     * @param grant The grant that holds the people who need to be associated
     * @param session The session
     */
    private void associatePeople(GrantItem item, Grant grant, Session session2) {
        //TODO add the removing of people who are no longer associated
        Session session = StoreHibernateUtil.getSessionFactory().openSession();
        try {
            LOGGER.debug("Associate People");
            for (Person person : grant.getAssociatedPeople()) {
                PersonItem personItem = personService_.getPersonItem(person.getExtId());
                ItemRelationId relationId = null;
                if (personItem != null) {
                    if (grant.getFirstInvestigator() != null
                            && person.getExtId().equals(grant.getFirstInvestigator().getExtId())) {
                        relationId = new ItemRelationId(item.getIid(), "hasPrincipalInvestigator",
                                personItem.getIid());
                    } else {
                        relationId = new ItemRelationId(item.getIid(), "hasAssociationWith", personItem.getIid());
                    }
                    ItemRelation relation = (ItemRelation) session.get(ItemRelation.class, relationId);
                    if (relation == null) {
                        LOGGER.debug("Adding Relation: {}, {}, {}", relationId.getIid(), relationId.getRelatedIid(),
                                relationId.getRelationValue());
                        relation = new ItemRelation();
                        relation.setId(relationId);
                        item.getItemRelationsForIid().add(relation);
                    } else {
                        LOGGER.debug("Found Relation: {}, {}, {}", relationId.getIid(), relationId.getRelatedIid(),
                                relationId.getRelationValue());
                    }
                } else {
                    LOGGER.error("Error finding and saving person with an id of: {}", person.getExtId());
                }
            }
        } finally {
            session.close();
        }
    }

    /**
     * Return the Grant with the given id
     * 
     * @param grantId The id of the grant to retrieve
     * @return The grant information
     */
    public Grant getGrant(String grantId) {
        Session session = StoreHibernateUtil.getSessionFactory().openSession();
        try {
            session.enableFilter("attributes");

            Query query = session.createQuery("FROM GrantItem WHERE extId = :extId");
            query.setParameter("extId", grantId);

            GrantItem item = (GrantItem) query.uniqueResult();
            Grant grant = getGrant(item);
            return grant;
        } finally {
            session.close();
        }
    }

    /**
     * Return the Grant from the given GrantItem
     * 
     * @param item The grant item to process
     * @return The grant
     */
    public Grant getGrant(GrantItem item) {
        Grant grant = new Grant();

        ItemTraitParser traitParser = new ItemTraitParser();
        try {
            grant = (Grant) traitParser.getItemObject(item, Grant.class);
        } catch (Exception e) {
            LOGGER.error("Exception getting grant", e);
        }

        String firstInvestigatorId = getSingleAttributeValue(item, StoreAttributes.FIRST_INVESTIGATOR_ID);
        Person firstInvestigator = personService_.getBasicPerson(firstInvestigatorId);
        grant.setFirstInvestigator(firstInvestigator);

        LOGGER.debug("Number of subjects?: {}", item.getAnzforSubjects().size());

        for (ItemRelation relation : item.getItemRelationsForIid()) {
            Item relatedItem = relation.getItemByRelatedIid();
            if (relatedItem instanceof PersonItem) {
                PersonItem personItem = (PersonItem) relatedItem;
                Person person = personService_.getBasicPerson(personItem);
                grant.getAssociatedPeople().add(person);
            }
        }

        return grant;
    }

    /**
     * Retrieves a list of grants associated with the person with the given id
     * 
     * @param staffId The staff id of the person to retrieve grants for
     * @return The list of grants
     */
    public List<Grant> getGrantsForPerson(String staffId) {
        Session session = StoreHibernateUtil.getSessionFactory().openSession();
        try {
            session.enableFilter("attributes");

            Query query = session.createQuery(
                    "SELECT grant FROM GrantItem grant, PersonItem person join person.itemRelationsForRelatedIid personRelation WHERE personRelation.itemByIid = grant and person.extId = :staffId");
            query.setParameter("staffId", staffId);
            @SuppressWarnings("unchecked")
            List<GrantItem> grantItems = query.list();
            List<Grant> grants = new ArrayList<Grant>();
            Grant grant = null;
            for (GrantItem grantItem : grantItems) {
                grant = getGrant(grantItem);
                if (grant != null) {
                    grants.add(grant);
                }
            }

            return grants;
        } finally {
            session.close();
        }
    }

    /**
     * Find grants with the given attributes and attribute values
     * 
     * @param attributes The attributes to query on
     * @return The grants
     */
    public List<Grant> queryGrantsByAttributes(Map<String, String> attributes) {
        List<Grant> grants = new ArrayList<Grant>();
        Session session = StoreHibernateUtil.getSessionFactory().openSession();
        session.enableFilter("attributes");

        try {
            List<String> parameters = new ArrayList<String>();

            StringBuilder fromString = new StringBuilder();
            StringBuilder whereString = new StringBuilder();

            fromString.append(" FROM GrantItem gi");
            whereString.append(" WHERE");
            int i = 0;
            for (Entry<String, String> entry : attributes.entrySet()) {
                fromString.append(" LEFT JOIN gi.itemAttributes gia");
                fromString.append(i);
                if (i > 0) {
                    whereString.append(" AND");
                }
                whereString.append(" gia");
                whereString.append(i);
                whereString.append(".attrType = ? AND lower(gia");
                whereString.append(i);
                whereString.append(".attrValue) like ?");
                parameters.add(entry.getKey());
                parameters.add("%" + entry.getValue().toLowerCase() + "%");

                i++;
            }
            String queryString = "SELECT gi " + fromString.toString() + " " + whereString.toString();
            LOGGER.info("Query: {}", queryString);
            LOGGER.info("Number of parameters: {}", parameters.size());
            Query query = session.createQuery(queryString);
            for (i = 0; i < parameters.size(); i++) {
                query.setParameter(i, parameters.get(i));
            }

            @SuppressWarnings("unchecked")
            List<GrantItem> grantItems = query.list();
            Grant grant = null;
            for (GrantItem grantItem : grantItems) {
                grant = getGrant(grantItem);
                grants.add(grant);
            }
        } finally {
            session.close();
        }

        return grants;
    }
}