at.thinkingco2.serverapplication.JourneyCalculation.java Source code

Java tutorial

Introduction

Here is the source code for at.thinkingco2.serverapplication.JourneyCalculation.java

Source

package at.thinkingco2.serverapplication;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.json.simple.JSONObject;

import at.thinkingco2.databasemanager.CarAccess;
import at.thinkingco2.databasemanager.JourneyAccess;
import at.thinkingco2.databasemanager.RouteAccess;
import at.thinkingco2.databasemanager.databeans.AddressBean;
import at.thinkingco2.databasemanager.databeans.ChildBean;
import at.thinkingco2.databasemanager.databeans.JourneyBean;
import at.thinkingco2.utils.ThinkingCO2Time;

/**
 * Methods for calculating the journeys
 * 
 * @author stefanspiss
 * 
 */
public class JourneyCalculation {
    private JourneyAccess jAccess;
    private RouteAccess rAccess;
    private final Long timeIntervall = (long) 900000; // 15min max. time between
    // the
    // arrival times.
    private final Double allowedTimeDiff = 30.0 * 60.0; // 30min max. time
    // longer way allowed
    private List<AddressBean> resultingAddressList;
    private List<JourneyBean> resultingJourneyList;
    private JSONObject resultingJSON;
    private JourneyBean bestFittingJourney;
    private Integer routeId;

    public JourneyCalculation() {
        this.jAccess = JourneyAccess.getInstance();
        this.rAccess = RouteAccess.getInstance();
        this.resultingAddressList = new ArrayList<AddressBean>();
        this.resultingJourneyList = new ArrayList<JourneyBean>();
    }

    /**
     * Method calculates for the simple journeyNew which Journey with a driver
     * can take it best.
     * 
     * @param journeyNew
     *            Journey without driver which is looking for a ride.
     * @return true if match found for journeyNew otherwise false.
     */
    public boolean addJourneyWithoutDriver(JourneyBean journeyNew) {
        boolean matchFound = false;
        if (journeyNew.getId() == null) {
            jAccess.addJourney(journeyNew);
        }

        List<JourneyBean> journeyListOfferingRide = jAccess.getJourneysWithDriver(journeyNew.getGroups());

        if (matchFound = this.calculateBestFittingJourney(journeyListOfferingRide, journeyNew)) {

            this.rAccess.deleteRoute(this.bestFittingJourney.getRouteId());
            this.routeId = this.rAccess.addRoute(this.resultingAddressList);

            for (JourneyBean i : this.resultingJourneyList) {
                i.setRouteId(routeId);
                this.jAccess.updateJourney(i);
            }
            System.out.println("used seats " + jAccess.getUsedSeats(routeId));
        }
        return matchFound;
    }

    /**
     * Method calculates for the journeyNew with a driver, if there are fitting
     * journeys without driver.
     * 
     * @param journeyNew
     *            Journey with driver which is looking for other journeys to
     *            take with.
     * @return true if match found for journeyNew otherwise false.
     */
    public boolean addJourneyWithDriver(JourneyBean journeyNew) {
        boolean matchFound = false;
        if (journeyNew.getId() == null) {
            jAccess.addJourney(journeyNew);
        }
        List<JourneyBean> journeyListSearchingRide = jAccess.getJourneysWithoutDriver(journeyNew.getGroups());

        for (int i = 0; i < journeyListSearchingRide.size(); ++i) {
            if (journeyListSearchingRide.get(i).getRouteId() != null) {
                journeyListSearchingRide.remove(i);
                i--;
            }
        }

        if (matchFound = this.calculateBestFittingJourney(journeyNew, journeyListSearchingRide)) {
            this.routeId = this.rAccess.addRoute(this.resultingAddressList);
            for (JourneyBean i : this.resultingJourneyList) {
                i.setRouteId(routeId);
                this.jAccess.updateJourney(i);
            }
        } else {
            journeyNew.setRouteId(this.rAccess.addRoute(this.resultingAddressList));
            this.jAccess.updateJourney(journeyNew);
        }
        return matchFound;
    }

    /**
     * Method calculates which journey out of the journeyList is best fitting to
     * take the journeyNew with it.
     * 
     * @param journeyListWihtDriver
     *            List of journeys which can be used to take the journeyNew with
     *            them
     * @param journeyWithoutDriver
     *            Journey which should be added to one of the journeys in the
     *            journeyList
     * @return true if match found for journeyWithoutDriver otherwise false.
     */
    private boolean calculateBestFittingJourney(List<JourneyBean> journeyListWihtDriver,
            JourneyBean journeyWithoutDriver) {
        this.clearObject();

        Timestamp time = journeyWithoutDriver.getArrivleTime();
        Integer numberChildrenAdd = journeyWithoutDriver.getChildren().size();
        boolean matchFound = false;

        List<JourneyBean> waypointList = new ArrayList<JourneyBean>();

        List<JourneyBean> tmpList = new ArrayList<JourneyBean>();

        Integer usedSeats;

        for (JourneyBean i : journeyListWihtDriver) {
            if (i.getRouteId() == null) {
                Set<ChildBean> childSet = i.getChildren();
                usedSeats = childSet.size() + 1;
            } else {
                usedSeats = jAccess.getUsedSeats(i.getRouteId());
            }
            if (ThinkingCO2Time.timestampsInIntervall(i.getArrivleTime(), time, timeIntervall)
                    && (usedSeats + numberChildrenAdd) < CarAccess.getInstance()
                            .getCarByLicenseNumber(i.getLicenseNumber()).getSeats()) {
                tmpList.add(i);
            }
        }

        MinimalJourney minJ = new MinimalJourney();
        Double duration;
        Double durationWithWaypoint;
        Double timeDiff = Double.MAX_VALUE;
        Integer routeID;

        for (JourneyBean i : tmpList) {
            waypointList.clear();

            if ((routeID = i.getRouteId()) != null) {
                waypointList.addAll(this.jAccess.getJourneysByRouteID(routeID));
                waypointList.remove(i);
            }

            minJ.minRoute(i, waypointList);
            duration = minJ.getDuration();

            waypointList.add(journeyWithoutDriver);

            minJ.minRoute(i, waypointList);
            durationWithWaypoint = minJ.getDuration();

            if ((durationWithWaypoint - duration) < timeDiff) {
                timeDiff = durationWithWaypoint - duration;
                this.bestFittingJourney = i;
                this.resultingAddressList = minJ.getAddressList();
                this.resultingJSON = minJ.getMinRouteJson();
                this.resultingJourneyList = waypointList;
                this.resultingJourneyList.add(i);
                matchFound = true;
            }
        }

        System.out.println("The new Journey: " + journeyWithoutDriver.toString());
        System.out.println("can be added to");
        if (bestFittingJourney != null) {
            System.out.println(bestFittingJourney.toString());
        } else {
            System.out.println("nobody");
        }
        System.out.println("Resulting AddressList: ");
        for (AddressBean i : this.resultingAddressList) {
            System.out.println(i.getCountry() + " " + i.getZip() + " " + i.getCity() + " " + i.getStreet() + " "
                    + i.getHousenumber());
        }
        return matchFound;
    }

    /**
     * Method calculates which journeys out of the journeyListWithoutDriver can
     * be taken from the journey driver.
     * 
     * @param driver
     *            JourneyBean with driver, which should be added and is looking
     *            for journeys to take with.
     * @param journeyListWithoutDriver
     *            List of journeys which should be added to the JourneyBean
     *            driver.
     * @return true if match found for driver otherwise false.
     */
    private boolean calculateBestFittingJourney(JourneyBean driver, List<JourneyBean> journeyListWithoutDriver) {
        this.clearObject();

        Timestamp time = driver.getArrivleTime();
        boolean matchFound = false;

        List<JourneyBean> tmpJourneyList = new ArrayList<JourneyBean>();
        JourneyBean tmpJourney;
        MinimalJourney minJ = new MinimalJourney();
        Double duration;
        Double durationWithWaypoint;
        Double timeDiff = 0.0;

        Integer numberChildrenAdd = 0;

        if (!journeyListWithoutDriver.isEmpty()) {
            numberChildrenAdd = journeyListWithoutDriver.get(0).getChildren().size();
        }
        Integer i = 0;

        Integer usedSeats;
        if (driver.getRouteId() == null) {
            Set<ChildBean> childSet = driver.getChildren();
            usedSeats = childSet.size() + 1;
        } else {
            usedSeats = jAccess.getUsedSeats(driver.getRouteId());
        }
        while ((usedSeats + numberChildrenAdd) < CarAccess.getInstance()
                .getCarByLicenseNumber(driver.getLicenseNumber()).getSeats()
                && i < journeyListWithoutDriver.size()) {
            if (ThinkingCO2Time.timestampsInIntervall(
                    (tmpJourney = journeyListWithoutDriver.get(i)).getArrivleTime(), time, timeIntervall)) {
                minJ.minRoute(driver, tmpJourneyList);
                duration = minJ.getDuration();
                tmpJourneyList.add(tmpJourney);
                minJ.minRoute(driver, tmpJourneyList);
                durationWithWaypoint = minJ.getDuration();

                if (timeDiff + (durationWithWaypoint - duration) < this.allowedTimeDiff) {
                    timeDiff += durationWithWaypoint - duration;
                    usedSeats += numberChildrenAdd;
                    matchFound = true;
                    System.out.println(i + 1 + " duration: " + duration);
                    System.out.println("duartion with waypoint: " + durationWithWaypoint);
                    System.out.println("used seats: " + usedSeats);
                } else {
                    tmpJourneyList.remove(tmpJourney);
                }
            }
            ++i;
            if (i < journeyListWithoutDriver.size()) {
                numberChildrenAdd = journeyListWithoutDriver.get(i).getChildren().size();
            }
        }

        minJ.minRoute(driver, tmpJourneyList);

        this.resultingAddressList = minJ.getAddressList();
        this.resultingJSON = minJ.getMinRouteJson();
        this.resultingJourneyList = tmpJourneyList;
        this.resultingJourneyList.add(driver);

        return matchFound;
    }

    private void clearObject() {
        this.bestFittingJourney = null;
        this.resultingAddressList.clear();
        this.resultingJSON = null;
        this.resultingJourneyList.clear();
        this.routeId = null;
    }

    public List<AddressBean> getResultingAddressList() {
        return resultingAddressList;
    }

    public JSONObject getResultingJSON() {
        return resultingJSON;
    }

    public Integer getRouteId() {
        return routeId;
    }
}