com.mothsoft.alexis.engine.numeric.TopicActivityDataSetImporter.java Source code

Java tutorial

Introduction

Here is the source code for com.mothsoft.alexis.engine.numeric.TopicActivityDataSetImporter.java

Source

/*   Copyright 2012 Tim Garrett, Mothsoft LLC
 *
 *  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.
 */
package com.mothsoft.alexis.engine.numeric;

import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

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

import org.apache.log4j.Logger;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.mothsoft.alexis.dao.DataSetDao;
import com.mothsoft.alexis.dao.DataSetPointDao;
import com.mothsoft.alexis.dao.DataSetTypeDao;
import com.mothsoft.alexis.dao.TopicDao;
import com.mothsoft.alexis.domain.DataSet;
import com.mothsoft.alexis.domain.DataSetPoint;
import com.mothsoft.alexis.domain.DataSetType;
import com.mothsoft.alexis.domain.Topic;
import com.mothsoft.alexis.domain.TopicActivityDataSet;

public class TopicActivityDataSetImporter implements DataSetImporter {

    private static final Logger logger = Logger.getLogger(TopicActivityDataSetImporter.class);

    @PersistenceContext
    private EntityManager em;

    private PlatformTransactionManager transactionManager;
    private TransactionTemplate transactionTemplate;

    private DataSetDao dataSetDao;
    private DataSetPointDao dataSetPointDao;
    private DataSetTypeDao dataSetTypeDao;
    private TopicDao topicDao;

    public TopicActivityDataSetImporter() {
        super();
    }

    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public void setDataSetDao(DataSetDao dataSetDao) {
        this.dataSetDao = dataSetDao;
    }

    public void setDataSetPointDao(DataSetPointDao dataSetPointDao) {
        this.dataSetPointDao = dataSetPointDao;
    }

    public void setDataSetTypeDao(DataSetTypeDao dataSetTypeDao) {
        this.dataSetTypeDao = dataSetTypeDao;
    }

    public void setTopicDao(TopicDao topicDao) {
        this.topicDao = topicDao;
    }

    @Override
    public void importData() {
        if (this.transactionTemplate == null) {
            this.transactionTemplate = new TransactionTemplate(this.transactionManager);
        }

        final List<Long> userIds = listUserIds();

        final GregorianCalendar calendar = new GregorianCalendar();
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        int minute = calendar.get(Calendar.MINUTE);

        if (minute >= 45) {
            calendar.set(Calendar.MINUTE, 30);
        } else if (minute >= 30) {
            calendar.set(Calendar.MINUTE, 15);
        } else if (minute >= 15) {
            calendar.set(Calendar.MINUTE, 0);
        } else if (minute >= 0) {
            calendar.set(Calendar.MINUTE, 45);
            calendar.add(Calendar.HOUR_OF_DAY, -1);
        }

        final Date startDate = calendar.getTime();

        calendar.add(Calendar.MINUTE, 15);
        calendar.add(Calendar.MILLISECOND, -1);
        final Date endDate = calendar.getTime();

        for (final Long userId : userIds) {
            importTopicDataForUser(userId, startDate, endDate);
        }
    }

    private List<Long> listUserIds() {
        final List<Long> userIds = this.transactionTemplate.execute(new TransactionCallback<List<Long>>() {

            @SuppressWarnings("unchecked")
            @Override
            public List<Long> doInTransaction(TransactionStatus txStatus) {
                final Query query = TopicActivityDataSetImporter.this.em
                        .createQuery("SELECT id FROM User ORDER BY id ASC");
                return query.getResultList();
            }
        });
        return userIds;
    }

    private void importTopicDataForUser(final Long userId, final Date startDate, final Date endDate) {
        logger.debug(String.format("Importing topic activity for user: %d between %s and %s", userId,
                startDate.toString(), endDate.toString()));

        final List<Long> topicIds = this.transactionTemplate.execute(new TransactionCallback<List<Long>>() {
            @SuppressWarnings("unchecked")
            @Override
            public List<Long> doInTransaction(TransactionStatus txStatus) {
                final Query query = TopicActivityDataSetImporter.this.em
                        .createQuery("SELECT id FROM Topic WHERE userId = :userId ORDER BY id ASC");
                query.setParameter("userId", userId);
                return query.getResultList();
            }
        });

        BigInteger total = BigInteger.ZERO;

        for (final Long topicId : topicIds) {
            BigInteger count = importTopicDataForTopic(topicId, startDate, endDate);
            total = total.add(count);
        }

        recordAggregateTopicActivity(userId, startDate, total);

    }

    private BigInteger importTopicDataForTopic(final Long topicId, final Date startDate, final Date endDate) {
        logger.debug(String.format("Importing topic activity for topic: %d between %s and %s", topicId,
                startDate.toString(), endDate.toString()));

        final String queryString = "SELECT DATE_FORMAT(td.creation_date, '%Y-%m-%d %H:00:00') as the_hour, "
                + " COUNT(td.id) from topic_document td INNER JOIN topic on topic.id = td.topic_id "
                + " WHERE td.creation_date >= ? AND td.creation_date <= ? AND td.topic_id = ? "
                + " GROUP BY the_hour ORDER BY td.creation_date";

        final BigInteger count = this.transactionTemplate.execute(new TransactionCallback<BigInteger>() {
            @Override
            public BigInteger doInTransaction(TransactionStatus txStatus) {
                final Query query = TopicActivityDataSetImporter.this.em.createNativeQuery(queryString);
                query.setParameter(1, startDate);
                query.setParameter(2, endDate);
                query.setParameter(3, topicId);

                final List<?> results = query.getResultList();

                if (results == null || results.isEmpty()) {
                    return BigInteger.ZERO;
                } else {
                    final Object[] array = (Object[]) results.get(0);
                    return (BigInteger) array[1];
                }
            }
        });

        logger.debug("Data set point: (" + startDate + ", " + count + ")");

        this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                TopicActivityDataSet dataSet = TopicActivityDataSetImporter.this.dataSetDao
                        .findTopicActivityDataSet(topicId);

                if (dataSet == null) {
                    final DataSetType type = TopicActivityDataSetImporter.this.dataSetTypeDao
                            .findSystemDataSetType(DataSetType.TOPIC_ACTIVITY);
                    final Topic topic = TopicActivityDataSetImporter.this.topicDao.get(topicId);
                    dataSet = new TopicActivityDataSet(topic, type);
                    TopicActivityDataSetImporter.this.em.persist(dataSet);
                }

                final DataSetPoint point = new DataSetPoint(dataSet, startDate, count.doubleValue());
                TopicActivityDataSetImporter.this.dataSetPointDao.add(point);
            }
        });

        return count;
    }

    private void recordAggregateTopicActivity(final Long userId, final Date startDate, final BigInteger total) {

        logger.debug("Recording aggregate topic activity for user: " + userId + "; (" + startDate.toString() + ", "
                + total + ")");

        this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus txStatus) {
                DataSet dataSet = TopicActivityDataSetImporter.this.dataSetDao
                        .findAggregateTopicActivityDataSet(userId);

                if (dataSet == null) {
                    final DataSetType type = TopicActivityDataSetImporter.this.dataSetTypeDao
                            .findSystemDataSetType(DataSetType.TOPIC_ACTIVITY);
                    dataSet = new DataSet(userId, "*All Topics*", type, true);
                    TopicActivityDataSetImporter.this.dataSetDao.add(dataSet);
                }

                final DataSetPoint totalPoint = new DataSetPoint(dataSet, startDate, total.doubleValue());
                TopicActivityDataSetImporter.this.dataSetPointDao.add(totalPoint);
            }
        });
    }
}