com.esofthead.mycollab.common.service.ibatis.TimelineTrackingServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.esofthead.mycollab.common.service.ibatis.TimelineTrackingServiceImpl.java

Source

/**
 * This file is part of mycollab-services.
 *
 * mycollab-services 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.
 *
 * mycollab-services 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 mycollab-services.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.esofthead.mycollab.common.service.ibatis;

import com.esofthead.mycollab.common.dao.TimelineTrackingCachingMapperExt;
import com.esofthead.mycollab.common.dao.TimelineTrackingMapper;
import com.esofthead.mycollab.common.dao.TimelineTrackingMapperExt;
import com.esofthead.mycollab.common.domain.GroupItem;
import com.esofthead.mycollab.common.domain.TimelineTracking;
import com.esofthead.mycollab.common.domain.criteria.TimelineTrackingSearchCriteria;
import com.esofthead.mycollab.common.service.TimelineTrackingService;
import com.esofthead.mycollab.core.UserInvalidInputException;
import com.esofthead.mycollab.core.arguments.SetSearchField;
import com.esofthead.mycollab.core.arguments.StringSearchField;
import com.esofthead.mycollab.core.persistence.ICrudGenericDAO;
import com.esofthead.mycollab.core.persistence.service.DefaultCrudService;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;

/**
 * @author MyCollab Ltd
 * @since 5.2.2
 */
@Service
public class TimelineTrackingServiceImpl extends DefaultCrudService<Integer, TimelineTracking>
        implements TimelineTrackingService {
    private static final Logger LOG = LoggerFactory.getLogger(TimelineTrackingServiceImpl.class);

    @Autowired
    private TimelineTrackingMapper timelineTrackingMapper;

    @Autowired
    private TimelineTrackingMapperExt timelineTrackingMapperExt;

    @Autowired
    private TimelineTrackingCachingMapperExt timelineTrackingCachingMapperExt;

    @Autowired
    private DataSource dataSource;

    @Override
    public ICrudGenericDAO<Integer, TimelineTracking> getCrudMapper() {
        return timelineTrackingMapper;
    }

    @Override
    public Map<String, List<GroupItem>> findTimelineItems(String fieldGroup, List<String> groupVals, Date start,
            Date end, TimelineTrackingSearchCriteria criteria) {
        try {
            DateTime startDate = new DateTime(start);
            final DateTime endDate = new DateTime(end);
            if (startDate.isAfter(endDate)) {
                throw new UserInvalidInputException("Start date must be greater than end date");
            }
            List<Date> dates = boundDays(startDate, endDate.minusDays(1));
            Map<String, List<GroupItem>> items = new HashMap<>();
            criteria.setFieldgroup(StringSearchField.and(fieldGroup));
            List<GroupItem> cacheTimelineItems = timelineTrackingCachingMapperExt.findTimelineItems(groupVals,
                    dates, criteria);

            DateTime calculatedDate = startDate.toDateTime();
            if (cacheTimelineItems.size() > 0) {
                GroupItem item = cacheTimelineItems.get(cacheTimelineItems.size() - 1);
                String dateValue = item.getGroupname();
                calculatedDate = DateTime.parse(dateValue, DateTimeFormat.forPattern("yyyy-MM-dd"));

                for (GroupItem map : cacheTimelineItems) {
                    String groupVal = map.getGroupid();
                    Object obj = items.get(groupVal);
                    if (obj == null) {
                        List<GroupItem> itemLst = new ArrayList<>();
                        itemLst.add(map);
                        items.put(groupVal, itemLst);
                    } else {
                        List<GroupItem> itemLst = (List<GroupItem>) obj;
                        itemLst.add(map);
                    }
                }
            }

            dates = boundDays(calculatedDate.plusDays(1), endDate);
            if (dates.size() > 0) {
                boolean isValidForBatchSave = true;
                final String type = criteria.getType().getValue();
                SetSearchField<Integer> extraTypeIds = criteria.getExtraTypeIds();
                Integer tmpExtraTypeId = null;
                if (extraTypeIds != null) {
                    if (extraTypeIds.getValues().size() == 1) {
                        tmpExtraTypeId = extraTypeIds.getValues().iterator().next();
                    } else {
                        isValidForBatchSave = false;
                    }
                }
                final Integer extraTypeId = tmpExtraTypeId;

                final List<Map> timelineItems = timelineTrackingMapperExt.findTimelineItems(groupVals, dates,
                        criteria);
                if (isValidForBatchSave) {
                    final Integer sAccountId = (Integer) criteria.getSaccountid().getValue();
                    final String itemFieldGroup = criteria.getFieldgroup().getValue();
                    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

                    final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
                    final List<Map> filterCollections = new ArrayList<>(
                            Collections2.filter(timelineItems, new Predicate<Map>() {
                                @Override
                                public boolean apply(Map input) {
                                    String dateStr = (String) input.get("groupname");
                                    DateTime dt = formatter.parseDateTime(dateStr);
                                    return !dt.equals(endDate);
                                }
                            }));
                    jdbcTemplate.batchUpdate(
                            "INSERT INTO `s_timeline_tracking_cache`(type, fieldval,extratypeid,sAccountId,"
                                    + "forDay, fieldgroup,count) VALUES(?,?,?,?,?,?,?)",
                            new BatchPreparedStatementSetter() {
                                @Override
                                public void setValues(PreparedStatement preparedStatement, int i)
                                        throws SQLException {
                                    Map item = filterCollections.get(i);
                                    preparedStatement.setString(1, type);
                                    String fieldVal = (String) item.get("groupid");
                                    preparedStatement.setString(2, fieldVal);
                                    preparedStatement.setInt(3, extraTypeId);
                                    preparedStatement.setInt(4, sAccountId);
                                    String dateStr = (String) item.get("groupname");
                                    DateTime dt = formatter.parseDateTime(dateStr);
                                    preparedStatement.setDate(5, new java.sql.Date(dt.toDate().getTime()));
                                    preparedStatement.setString(6, itemFieldGroup);
                                    int value = ((BigDecimal) item.get("value")).intValue();
                                    preparedStatement.setInt(7, value);
                                }

                                @Override
                                public int getBatchSize() {
                                    return filterCollections.size();
                                }
                            });
                }

                for (Map map : timelineItems) {
                    String groupVal = (String) map.get("groupid");
                    GroupItem item = new GroupItem();
                    item.setValue(((BigDecimal) map.get("value")).doubleValue());
                    item.setGroupid((String) map.get("groupid"));
                    item.setGroupname((String) map.get("groupname"));
                    Object obj = items.get(groupVal);
                    if (obj == null) {
                        List<GroupItem> itemLst = new ArrayList<>();
                        itemLst.add(item);
                        items.put(groupVal, itemLst);
                    } else {
                        List<GroupItem> itemLst = (List<GroupItem>) obj;
                        itemLst.add(item);
                    }
                }
            }

            return items;
        } catch (Exception e) {
            LOG.error("Error", e);
            return null;
        }
    }

    private List<Date> boundDays(DateTime start, DateTime end) {
        Duration duration = new Duration(start, end);
        long days = duration.getStandardDays();
        List<Date> dates = new ArrayList<>();
        //Will try to get from cache values from the end date to (startdate - 1)
        for (int i = 0; i <= days; i++) {
            dates.add(start.plusDays(i).toDate());
        }
        return dates;
    }
}