Java tutorial
/* 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); } }); } }