com.ushahidi.swiftriver.core.api.dao.impl.AbstractJpaContextDropDao.java Source code

Java tutorial

Introduction

Here is the source code for com.ushahidi.swiftriver.core.api.dao.impl.AbstractJpaContextDropDao.java

Source

/**
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.ushahidi.swiftriver.core.api.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.ushahidi.swiftriver.core.api.dao.ContextDropDao;
import com.ushahidi.swiftriver.core.api.dao.GenericDao;
import com.ushahidi.swiftriver.core.model.Account;
import com.ushahidi.swiftriver.core.model.Bucket;
import com.ushahidi.swiftriver.core.model.Drop;
import com.ushahidi.swiftriver.core.model.Link;
import com.ushahidi.swiftriver.core.model.Media;
import com.ushahidi.swiftriver.core.model.MediaThumbnail;
import com.ushahidi.swiftriver.core.model.Place;
import com.ushahidi.swiftriver.core.model.Tag;

public abstract class AbstractJpaContextDropDao<T> extends AbstractJpaDao<T>
        implements ContextDropDao, GenericDao<T> {

    /**
     * Query to be used for retrieving tag metadata for drops in a River/Bucket
     */
    protected String tagsQuery = null;

    /**
     * Query to be used for retrieving link metadata for drops in a River/Bucket
     */
    protected String linksQuery = null;

    /**
     * Query to be used for retrieving the drop image drops in a River/Bucket
     */
    protected String dropImageQuery = null;

    /**
     * Query to be used for retrieving media metadata for drops in a River/Bucket
     */
    protected String mediaQuery = null;

    /**
     * Query to be used for retrieving place metadata for drops in a River/Bucket
     */
    protected String placesQuery = null;

    /**
     * Query to be used for retrieving the context id for drops in a River/Bucket
     */
    protected String contextDropQuery = null;

    @PersistenceContext
    protected EntityManager em;

    protected NamedParameterJdbcTemplate namedJdbcTemplate;

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.namedJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.ushahidi.swiftriver.core.api.dao.ContextDropDao#populateMetadata(
     * java.util.List, com.ushahidi.swiftriver.core.model.Account)
     */
    @Override
    public void populateMetadata(List<Drop> drops, Account queryingAccount) {
        if (drops.size() == 0) {
            return;
        }

        populateTags(drops);
        populateLinks(drops);
        populateMedia(drops);
        populatePlaces(drops);
        populateBuckets(drops, queryingAccount);
        populateForms(drops);
    }

    /**
     * Populate tag metadata into the given drops.
     * 
     * @param drops
     * @param dropSource
     */
    public void populateTags(List<Drop> drops) {

        List<Long> dropIds = new ArrayList<Long>();
        for (Drop drop : drops) {
            dropIds.add(drop.getId());
        }

        Query query = em.createNativeQuery(tagsQuery);
        query.setParameter("drop_ids", dropIds);

        // Group the tags by drop id
        Map<Long, List<Tag>> tags = new HashMap<Long, List<Tag>>();
        for (Object oRow : query.getResultList()) {
            Object[] r = (Object[]) oRow;

            Long dropId = ((Number) r[0]).longValue();
            Tag tag = new Tag();
            tag.setId(((Number) r[1]).longValue());
            tag.setTag((String) r[2]);
            tag.setType((String) r[4]);

            List<Tag> t = tags.get(dropId);
            if (t == null) {
                t = new ArrayList<Tag>();
                tags.put(dropId, t);
            }

            t.add(tag);
        }

        for (Drop drop : drops) {
            List<Tag> t = tags.get(drop.getId());

            if (t != null) {
                drop.setTags(t);
            } else {
                drop.setTags(new ArrayList<Tag>());
            }
        }

    }

    /**
     * Populate link metadata into the given drops array.
     * 
     * @param drops
     * @param dropSource
     */
    public void populateLinks(List<Drop> drops) {

        List<Long> dropIds = new ArrayList<Long>();
        for (Drop drop : drops) {
            dropIds.add(drop.getId());
        }

        Query query = em.createNativeQuery(linksQuery);
        query.setParameter("drop_ids", dropIds);

        // Group the links by drop id
        Map<Long, List<Link>> links = new HashMap<Long, List<Link>>();
        for (Object oRow : query.getResultList()) {
            Object[] r = (Object[]) oRow;

            Long dropId = ((Number) r[0]).longValue();
            Link link = new Link();
            link.setId(((Number) r[1]).longValue());
            link.setUrl((String) r[2]);

            List<Link> l = links.get(dropId);
            if (l == null) {
                l = new ArrayList<Link>();
                links.put(dropId, l);
            }

            l.add(link);
        }

        for (Drop drop : drops) {
            List<Link> l = links.get(drop.getId());

            if (l != null) {
                drop.setLinks(l);
            } else {
                drop.setLinks(new ArrayList<Link>());
            }
        }
    }

    /**
     * Populate media metadata into the given drops array.
     * 
     * @param drops
     * @param dropSource
     */
    public void populateMedia(List<Drop> drops) {

        Map<Long, Integer> dropIndex = new HashMap<Long, Integer>();
        int i = 0;
        for (Drop drop : drops) {
            dropIndex.put(drop.getId(), i);
            i++;
        }

        Query query = em.createNativeQuery(dropImageQuery);
        query.setParameter("drop_ids", dropIndex.keySet());

        Map<Long, Long> dropImagesMap = new HashMap<Long, Long>();
        for (Object oRow2 : query.getResultList()) {
            Object[] r2 = (Object[]) oRow2;
            dropImagesMap.put(((Number) r2[0]).longValue(), ((Number) r2[1]).longValue());
        }

        query = em.createNativeQuery(mediaQuery);
        query.setParameter("drop_ids", dropIndex.keySet());

        // Group the media by drop id
        for (Object oRow : query.getResultList()) {
            Object[] r = (Object[]) oRow;

            Long dropId = ((Number) r[0]).longValue();
            Drop drop = drops.get(dropIndex.get(dropId));
            if (drop.getMedia() == null) {
                drop.setMedia(new ArrayList<Media>());
            }

            Long mediaId = ((Number) r[1]).longValue();
            Media m = null;
            for (Media x : drop.getMedia()) {
                if (x.getId() == mediaId) {
                    m = x;
                }
            }

            if (m == null) {
                m = new Media();
                m.setId(mediaId);
                m.setUrl((String) r[2]);
                m.setType((String) r[3]);
            }

            // Add thumbnails
            if (r[4] != null) {
                MediaThumbnail mt = new MediaThumbnail();
                mt.setMedia(m);
                mt.setSize((Integer) r[4]);
                mt.setUrl((String) r[5]);

                List<MediaThumbnail> thumbnails = m.getThumbnails();
                if (thumbnails == null) {
                    thumbnails = new ArrayList<MediaThumbnail>();
                    m.setThumbnails(thumbnails);
                }
                thumbnails.add(mt);
            }

            if (!drop.getMedia().contains(m)) {
                drop.getMedia().add(m);

                // Set the droplet image if any
                Long dropImageId = dropImagesMap.get(drop.getId());
                if (dropImageId != null && dropImageId == m.getId()) {
                    drop.setImage(m);
                }
            }
        }
    }

    /**
     * Populate geo metadata into the given drops array.
     * 
     * @param drops
     * @param dropSource
     */
    public void populatePlaces(List<Drop> drops) {

        Map<Long, Integer> dropIndex = new HashMap<Long, Integer>();
        int i = 0;
        for (Drop drop : drops) {
            dropIndex.put(drop.getId(), i);
            i++;
        }

        Query query = em.createNativeQuery(placesQuery);
        query.setParameter("drop_ids", dropIndex.keySet());

        // Group the media by drop id
        Map<Long, Place> places = new HashMap<Long, Place>();
        for (Object oRow : query.getResultList()) {
            Object[] r = (Object[]) oRow;

            Long dropId = ((Number) r[0]).longValue();
            Drop drop = drops.get(dropIndex.get(dropId));
            if (drop.getPlaces() == null) {
                drop.setPlaces(new ArrayList<Place>());
            }

            Long placeId = ((Number) r[1]).longValue();
            Place p = places.get(placeId);

            if (p == null) {
                p = new Place();
                p.setId(placeId);
                p.setPlaceName((String) r[2]);
                p.setLatitude(((Number) r[5]).floatValue());
                p.setLongitude(((Number) r[6]).floatValue());

                places.put(placeId, p);
            }

            // Add place to drop
            if (!drop.getPlaces().contains(p)) {
                drop.getPlaces().add(p);
            }
        }
    }

    /**
     * Populates the buckets for each of the {@link Drop} in <code>drops</code>
     * 
     * @param drops
     * @param queryingAccount
     * @param dropSource
     */
    public void populateBuckets(List<Drop> drops, Account queryingAccount) {
        Map<Long, Integer> dropsIndex = new HashMap<Long, Integer>();
        int i = 0;
        for (Drop drop : drops) {
            dropsIndex.put(drop.getId(), i);
            i++;
        }

        // Query to fetch the buckets
        String sql = "SELECT `buckets_droplets`.`droplet_id` AS `id`, `buckets`.`id` AS `bucket_id`, `buckets`.`bucket_name` ";
        sql += "FROM `buckets` ";
        sql += "INNER JOIN `buckets_droplets` ON (`buckets`.`id` = `buckets_droplets`.`bucket_id`) ";
        sql += "WHERE `buckets_droplets`.`droplet_id` IN (:dropletIds) ";
        sql += "AND `buckets`.`bucket_publish` = 1 ";
        sql += "UNION ALL ";
        sql += "SELECT `buckets_droplets`.`droplet_id` AS `id`, `buckets`.`id` AS `bucket_id`, `buckets`.`bucket_name` ";
        sql += "FROM `buckets` ";
        sql += "INNER JOIN `buckets_droplets` ON (`buckets`.`id` = `buckets_droplets`.`bucket_id`) ";
        sql += "LEFT JOIN `accounts` ON (`buckets`.`account_id` = `accounts`.`id` AND `buckets`.`account_id` = :accountId) ";
        sql += "LEFT JOIN `bucket_collaborators` ON (`bucket_collaborators`.`bucket_id` = `buckets`.`id` AND `bucket_collaborators`.`account_id` = :accountId) ";
        sql += "WHERE `buckets_droplets`.`droplet_id` IN (:dropletIds) ";
        sql += "AND `buckets`.`bucket_publish` = 0 ";

        MapSqlParameterSource params = new MapSqlParameterSource();
        params.addValue("dropletIds", dropsIndex.keySet());
        params.addValue("accountId", (Long) queryingAccount.getId());
        List<Map<String, Object>> results = this.namedJdbcTemplate.queryForList(sql, params);

        // Group the buckets per drop 
        Map<Long, List<Bucket>> dropBucketsMap = new HashMap<Long, List<Bucket>>();
        for (Map<String, Object> row : results) {

            Long bucketDropId = ((Number) row.get("id")).longValue();
            List<Bucket> dropBuckets = dropBucketsMap.get(bucketDropId);
            if (dropBuckets == null) {
                dropBuckets = new ArrayList<Bucket>();
            }

            // Create the bucket
            Bucket bucket = new Bucket();
            bucket.setId(((Number) row.get("bucket_id")).longValue());
            bucket.setName((String) row.get("bucket_name"));

            // Add to the list of buckets for the current drop
            dropBuckets.add(bucket);
            dropBucketsMap.put(bucketDropId, dropBuckets);
        }

        // Populate the buckets for the submitted drops
        for (Map.Entry<Long, List<Bucket>> entry : dropBucketsMap.entrySet()) {
            Long dropId = entry.getKey();

            // Retrieve the drop
            Drop drop = drops.get(dropsIndex.get(dropId));
            drop.setBuckets(entry.getValue());
        }
    }

    /**
     * Populate custom field for the given drops.
     * 
     * @param drops
     */
    public abstract void populateForms(List<Drop> drops);

}