com.dalamar.watcher.TrainStationWatcher.java Source code

Java tutorial

Introduction

Here is the source code for com.dalamar.watcher.TrainStationWatcher.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.dalamar.watcher;

import com.dalamar.harvest.BasicHarvester;
import com.dalamar.model.LateTrain;
import com.dalamar.model.LateTrainDao;
import com.dalamar.sorting.TrainComparators;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.jsoup.Connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

/**
 *
 * @author Dimitar
 */
public class TrainStationWatcher {

    private String name;
    private static final String INITIAL_URL = "http://razpisanie.bdz.bg/SearchServlet?action=listStationDelay&fromStationName=";
    private Date date;

    LateTrainDao ltd = null;

    public TrainStationWatcher(String stationName, LateTrainDao lateTrainDao) {
        this.name = stationName;
        this.ltd = lateTrainDao;
        this.date = Calendar.getInstance().getTime();

    }

    public TrainStationWatcher(String stationName, LateTrainDao lateTrainDao, Date customDate) {
        this.name = stationName;
        this.ltd = lateTrainDao;
        this.date = customDate;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public LateTrain[] fetchLateTrains() throws IOException {
        Calendar cl = Calendar.getInstance();
        String timestamp = new SimpleDateFormat("d/M/yyyy").format(this.date);

        String URL = INITIAL_URL + this.name + "&delayDate=" + timestamp;

        ArrayList<String> selectors = new ArrayList<String>();
        selectors.add("tr[bgcolor=#f9f4c9]");
        BasicHarvester bh;
        bh = new BasicHarvester(URL, selectors);

        Map<String, Object> resultMap = bh.harvest();

        ArrayList<LateTrain> arlist = new ArrayList<LateTrain>();

        for (Map.Entry entry : resultMap.entrySet()) {
            for (String[] ls : (ArrayList<String[]>) entry.getValue()) {
                LateTrain tmp = new LateTrain(ls);
                tmp.setToStation(name);
                tmp.setInSum(1);
                arlist.add(tmp);
            }
        }

        LateTrain[] toReturn = new LateTrain[arlist.size()];

        arlist.toArray(toReturn);

        return toReturn;
    }

    public void diffWithDB() {

        ArrayList<LateTrain> trainsInDB = (ArrayList<LateTrain>) ltd.clear().betweenDates(date, date).station(name)
                .executeQuery();

        LateTrain[] trains = null;
        try {
            trains = fetchLateTrains();
        } catch (IOException ex) {
            Logger.getLogger(TrainStationWatcher.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (trains == null)
            return;

        if (trainsInDB.isEmpty()) {
            for (LateTrain tr : trains) {
                tr.setToStation(name);
                tr.setDateCaptured(date); // temporary for test. please fix later to Calendar.getInstance().getTime();
                ltd.save(tr);
            }
        }

        else {
            HashMap<String, LateTrain> trainNumToTrain = getTrainMap(trainsInDB);
            for (LateTrain tr : trains) {
                if (trainNumToTrain.containsKey(tr.getTrainNumber())) {
                    diffSingleTrain(tr, trainNumToTrain);
                } else {
                    tr.setToStation(this.name);
                    tr.setDateCaptured(date);// temporary for test. please fix later to Calendar.getInstance().getTime();
                    ltd.save(tr);
                }
            }
        }

        rectifyInDB();

    }

    private HashMap<String, LateTrain> getTrainMap(ArrayList<LateTrain> trainsInDB) {
        HashMap<String, LateTrain> map = new HashMap<String, LateTrain>();
        for (LateTrain tr : trainsInDB) {
            map.put(tr.getTrainNumber(), tr);
        }
        return map;
    }

    private void diffSingleTrain(LateTrain tr, Map<String, LateTrain> map) {
        LateTrain oldEntry = map.get(tr.getTrainNumber());
        boolean updated = false;

        //update delay
        if (tr.getDelay() != oldEntry.getDelay()) {
            oldEntry.setDelay(tr.getDelay());
            updated = true;
        }
        if (!tr.getReason().equals(oldEntry.getReason())) {
            oldEntry.setReason(tr.getReason());
            updated = true;
        }

        if (updated)
            ltd.update(oldEntry);

    }

    private void rectifyInDB() {
        LateTrainDao template = ltd.clear().betweenDates(date, date).withDelay(true).saveTemplate();
        ArrayList<String> trainNums = (ArrayList<String>) template.saveTemplate().groupBy("trainNumber")
                .executeQuery();

        HashMap<String, ArrayList<LateTrain>> match = new HashMap<String, ArrayList<LateTrain>>();

        for (String lt : trainNums) {
            LateTrainDao current = template.saveTemplate().custom(Restrictions.eq("trainNumber", lt));
            ArrayList<LateTrain> currentTrains = (ArrayList<LateTrain>) current.executeQuery();
            int amount = currentTrains.size();
            if (amount > 1) {
                Collections.sort(currentTrains, TrainComparators.TIME_ASCENDING);
                int max = 0;
                int maxId = 0;
                int accumulatedDelay;
                accumulatedDelay = currentTrains.get(0).getDelay();

                for (int i = 1; i < currentTrains.size(); i++) {
                    LateTrain currentTrain = currentTrains.get(i);
                    currentTrain.setInSum(0);
                    int adjustedDelay = currentTrain.getDelay() - accumulatedDelay;
                    if (adjustedDelay < 0)
                        adjustedDelay = 0;
                    currentTrain.setAdjustedDelay(adjustedDelay);
                    currentTrain.setPreviouslyDelayedStation(currentTrains.get(i - 1).getToStation());
                    if (adjustedDelay > 0)
                        accumulatedDelay += adjustedDelay;
                    ltd.update(currentTrain);
                }
            }

        }
    }
}