Axel Nordh 3 anos atrás
pai
commit
64b746dc12

+ 0 - 60
ATG/src/controllers/ComparingController.java

@@ -1,60 +0,0 @@
-package controllers;
-
-import java.net.URL;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.List;
-import java.util.ResourceBundle;
-import java.util.stream.Collectors;
-
-import com.google.common.collect.Lists;
-
-import javafx.application.Platform;
-import javafx.fxml.FXML;
-import javafx.fxml.Initializable;
-import javafx.scene.control.Button;
-import javafx.scene.control.DatePicker;
-import javafx.scene.control.TabPane;
-import objects.HorseRaceData;
-import objects.RaceTableView;
-
-public class ComparingController implements Initializable {
-
-	@FXML Button submitButton;
-	@FXML DatePicker datePicker;
-	@FXML TabPane mainComparingTableView;
-
-	List<SimpleEntry<String, List<HorseRaceData>>> racesByTrack = Lists.newArrayList();
-
-	@Override
-	public void initialize(URL arg0, ResourceBundle arg1) {
-
-		datePicker.valueProperty().addListener((observable, oldValue, newValue) -> {
-			if (newValue == null) {
-				submitButton.setDisable(true);
-			} else {
-				submitButton.setDisable(false);
-			}
-		});
-
-	}
-
-
-	@FXML
-	public void submitAction() {
-		submitButton.setDisable(true);
-
-		Platform.runLater(() -> {
-			final List<HorseRaceData> todaysRaces = DatabaseController.getInstance().getTodaysRaces("", datePicker.getValue().toString(), false);
-
-			final List<String> tracks = todaysRaces.stream().map(m -> m.getTrackName()).distinct().collect(Collectors.toList());
-			mainComparingTableView.getTabs().clear();
-			for (final String t : tracks) {
-				final SimpleEntry<String, List<HorseRaceData>> trackRaces = new SimpleEntry<String,List<HorseRaceData>>(t,
-						todaysRaces.stream().filter(p -> p.getTrackName().equals(t)).collect(Collectors.toList()));
-				racesByTrack.add(trackRaces);
-				mainComparingTableView.getTabs().add(new RaceTableView(trackRaces));
-			}
-			submitButton.setDisable(false);
-		});
-	}
-}

+ 51 - 0
ATG/src/controllers/DatabaseController.java

@@ -1578,4 +1578,55 @@ public class DatabaseController {
         return res;
     }
 
+    public void setfullStatsCollected(String who, int travsportId, String date) {
+        String sql;
+        if ("horse".equals(who)) {
+            sql = "UPDATE Horse SET fullStatsCollected = ? WHERE travsportId = ?";
+        } else if ("driver".equals(who)) {
+            sql = "UPDATE Driver SET fullStatsCollected = ? WHERE travsportId = ?";
+        } else {
+            throw new RuntimeException("Unknown who: " + who);
+        }
+
+        try {
+            final PreparedStatement stat = getConnection().prepareStatement(sql);
+            stat.setString(1, date);
+            stat.setInt(2, travsportId);
+
+            stat.executeUpdate();
+        } catch (final SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    public String getFullStatsCollected(String who, int travsportId) {
+        final String sql;
+        String result = null;
+        if ("horse".equals(who)) {
+            sql = "SELECT fullStatsCollected FROM Horse WHERE travsportId = ?";
+        } else if ("driver".equals(who)) {
+            sql = "SELECT fullStatsCollected FROM Driver WHERE travsportId = ?";
+        } else {
+            throw new RuntimeException("Failed to get Full stats");
+        }
+
+        try {
+            final PreparedStatement stat = getConnection().prepareStatement(sql);
+            stat.setInt(1, travsportId);
+
+            final ResultSet rs = stat.executeQuery();
+
+            while (rs.next()) {
+                result = rs.getString("fullStatsCollected");
+
+            }
+        } catch (final SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        return result;
+    }
+
 }

+ 102 - 138
ATG/src/controllers/MainController.java

@@ -2,11 +2,7 @@ package controllers;
 
 import java.net.URL;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.ResourceBundle;
-import java.util.concurrent.TimeUnit;
-
-import com.google.common.base.Stopwatch;
 
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
@@ -17,143 +13,111 @@ import javafx.fxml.Initializable;
 import javafx.scene.control.Button;
 import javafx.scene.control.DatePicker;
 import javafx.scene.control.TextField;
-import objects.DaysSinceLastRace;
 import objects.DaysSinceLastRaceSummary;
 import parsers.TravsportParser;
 
 public class MainController implements Initializable {
 
-	@FXML private Button getHorseStatsButton;
-	@FXML private Button getDriverStatsButton;
-	@FXML private Button racesByDate;
-	@FXML private TextField horseNameTextField;
-	@FXML private TextField driverFirstNameTextField;
-	@FXML private TextField driverLastNameTextField;
-	@FXML private Button testButton;
-	@FXML private Button updateResultsButton;
-	@FXML private V75TabController V75TabController;
-	@FXML private LDTabController LDTabController;
-	@FXML public DatePicker datePicker;
-
-	public static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
-	private int mRaceId;
-	private final DaysSinceLastRaceSummary driverLastRaceSummary = new DaysSinceLastRaceSummary();
-
-	@Override
-	public void initialize(URL arg0, ResourceBundle arg1) {
-		updateRaceId();
-
-		horseNameTextField.textProperty().addListener(new ChangeListener<String>() {
-			@Override
-			public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
-				if (newValue.length() > 1) {
-					getHorseStatsButton.setDisable(false);
-				} else {
-					getHorseStatsButton.setDisable(true);
-				}
-			}
-		});
-
-		driverFirstNameTextField.textProperty().addListener(new ChangeListener<String>() {
-			@Override
-			public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
-				if (newValue.length() > 1) {
-					getDriverStatsButton.setDisable(false);
-				} else {
-					getDriverStatsButton.setDisable(true);
-				}
-			}
-
-		});
-		driverLastNameTextField.textProperty().addListener(new ChangeListener<String>() {
-			@Override
-			public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
-				if (newValue.length() > 1) {
-					getDriverStatsButton.setDisable(false);
-				} else {
-					getDriverStatsButton.setDisable(true);
-				}
-			}
-
-		});
-
-		//		getDriverLastRacesStat();
-	}
-
-	private void getDriverLastRacesStat() {
-		final DatabaseController db = DatabaseController.getInstance();
-		final ArrayList<Integer> driverIds = db.getDriverIds();
-
-		final Stopwatch createStarted = Stopwatch.createStarted();
-		driverIds.forEach(di -> {
-			final ArrayList<DaysSinceLastRace> driverDaysSinceLastRaceStats = db.getDriverDaysSinceLastRaceStats(di);
-			driverDaysSinceLastRaceStats.forEach( d -> driverLastRaceSummary.addStats(d));
-		});
-		createStarted.stop();
-		System.out.println("Execution time: " + createStarted.elapsed(TimeUnit.SECONDS));
-	}
-
-	private void updateRaceId() {
-		mRaceId = DatabaseController.getInstance().getRaceId();
-		if (mRaceId != -1) {
-			updateResultsButton.setDisable(false);
-		} else {
-			updateResultsButton.setDisable(true);
-		}
-	}
-
-	@FXML
-	public void GetHorseStatsAction() { // Test class
-		final int horseId = TravsportParser.getInstance().getHorseIdByName(horseNameTextField.getText());
-		System.out.println("Getting stats for horse " + horseNameTextField.getText() + " with id: " + horseId);
-		TravsportParser.getInstance().getHorseStatByIdJson(horseId, horseNameTextField.getText(), "", -1);
-	}
-
-	@FXML
-	public void GetDriverStatsAction() { // Test class
-		final String firstName = driverFirstNameTextField.getText().trim();
-		final String lastName = driverLastNameTextField.getText().trim();
-		int driverId = DatabaseController.getInstance().getDriverTravsportId(firstName, lastName);
-		if (driverId <= 0) {
-			driverId = TravsportParser.getInstance().getDriverIdByName(firstName, lastName);
-		}
-		TravsportParser.getInstance().getDriverStatById(driverId, lastName + " " + firstName, -1);
-	}
-
-	@FXML
-	public void TestAction() {
-		System.out.println("TEST ACTION");
-
-
-		//		final LocalDate startDate = LocalDate.parse("2021-01-01");
-		//
-		//		final LocalDate endDate = LocalDate.parse("2021-02-04");
-		//
-		//		for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusMonths(1)) {
-		//			TravsportParser.getInstance().getRaceResults(date.withDayOfMonth(1).toString(), date.withDayOfMonth(date.lengthOfMonth()).toString()); // behöver tweakas innan man kan mass hämta resultat
-		//		}
-
-
-		// Build test file
-		//		DatabaseController.getInstance().getTestDataToFile();
-
-	}
-
-	@FXML public void UpdateResults() {
-
-		updateResultsButton.setDisable(true);
-		Platform.runLater(() -> {
-			while (mRaceId > 0) {
-				TravsportParser.getInstance().updateRaceResults(mRaceId);
-				DatabaseController.getInstance().removeRaceIds(mRaceId); // Strukna hästar tas bort från rättningen
-				updateRaceId();
-			}
-		});
-	}
-
-	@FXML public void MainTabSelectionChange(Event e) {
-		//		if (((Tab)e.getTarget()).getText().equals("Main")) {
-		//			updateRaceId();
-		//		}
-	}
+    @FXML private Button getHorseStatsButton;
+    @FXML private Button getDriverStatsButton;
+    @FXML private Button racesByDate;
+    @FXML private TextField horseNameTextField;
+    @FXML private TextField driverFirstNameTextField;
+    @FXML private TextField driverLastNameTextField;
+    @FXML private Button testButton;
+    @FXML private Button updateResultsButton;
+    @FXML private V75TabController V75TabController;
+    @FXML private LDTabController LDTabController;
+    @FXML public DatePicker datePicker;
+
+    public static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+    private int mRaceId;
+    private final DaysSinceLastRaceSummary driverLastRaceSummary = new DaysSinceLastRaceSummary();
+
+    @Override
+    public void initialize(URL arg0, ResourceBundle arg1) {
+        updateRaceId();
+
+        horseNameTextField.textProperty().addListener(new ChangeListener<String>() {
+            @Override
+            public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
+                if (newValue.length() > 1) {
+                    getHorseStatsButton.setDisable(false);
+                } else {
+                    getHorseStatsButton.setDisable(true);
+                }
+            }
+        });
+
+        driverFirstNameTextField.textProperty().addListener(new ChangeListener<String>() {
+            @Override
+            public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
+                if (newValue.length() > 1) {
+                    getDriverStatsButton.setDisable(false);
+                } else {
+                    getDriverStatsButton.setDisable(true);
+                }
+            }
+
+        });
+        driverLastNameTextField.textProperty().addListener(new ChangeListener<String>() {
+            @Override
+            public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
+                if (newValue.length() > 1) {
+                    getDriverStatsButton.setDisable(false);
+                } else {
+                    getDriverStatsButton.setDisable(true);
+                }
+            }
+
+        });
+    }
+
+    private void updateRaceId() {
+        mRaceId = DatabaseController.getInstance().getRaceId();
+        if (mRaceId != -1) {
+            updateResultsButton.setDisable(false);
+        } else {
+            updateResultsButton.setDisable(true);
+        }
+    }
+
+    @FXML
+    public void GetHorseStatsAction() { // Test class
+        final int horseId = TravsportParser.getInstance().getHorseIdByName(horseNameTextField.getText());
+        System.out.println("Getting stats for horse " + horseNameTextField.getText() + " with id: " + horseId);
+        TravsportParser.getInstance().getHorseStatByIdJson(horseId, horseNameTextField.getText(), "", -1);
+    }
+
+    @FXML
+    public void GetDriverStatsAction() { // Test class
+        final String firstName = driverFirstNameTextField.getText().trim();
+        final String lastName = driverLastNameTextField.getText().trim();
+        int driverId = DatabaseController.getInstance().getDriverTravsportId(firstName, lastName);
+        if (driverId <= 0) {
+            driverId = TravsportParser.getInstance().getDriverIdByName(firstName, lastName);
+        }
+        TravsportParser.getInstance().getDriverStatById(driverId, lastName + " " + firstName, -1);
+    }
+
+    @FXML
+    public void TestAction() {
+        System.out.println("TEST ACTION");
+    }
+
+    @FXML
+    public void UpdateResults() {
+        updateResultsButton.setDisable(true);
+        Platform.runLater(() -> {
+            while (mRaceId > 0) {
+                TravsportParser.getInstance().updateRaceResults(mRaceId);
+                DatabaseController.getInstance().removeRaceIds(mRaceId); // Strukna hästar tas bort från rättningen
+                updateRaceId();
+            }
+        });
+    }
+
+    @FXML
+    public void MainTabSelectionChange(Event e) {
+    }
 }

+ 275 - 259
ATG/src/controllers/TestTabController.java

@@ -16,6 +16,7 @@ import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.fxml.FXML;
 import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
 import javafx.scene.control.ChoiceBox;
 import javafx.scene.control.DatePicker;
 import javafx.scene.control.TableColumn;
@@ -27,263 +28,278 @@ import parsers.TravsportParser;
 @SuppressWarnings("rawtypes")
 public class TestTabController extends AtgController {
 
-	@FXML Pane DDButtonPane;
-	@FXML Pane DDResultPane;
-	@FXML DatePicker datePicker;
-	@FXML Button getRacesButton;
-	@FXML Button getRacesForDateButton;
-	@FXML Button getRaceCalendarButton;
-	@FXML ChoiceBox<String> raceTypeSelector;
-
-	@FXML TableColumn<Map, Float> horseAvarageWithModifiersColumn = new TableColumn<>("horseAvgModified");
-	@FXML TableColumn<Map, Float> driverAvarageWithModifiersColumn = new TableColumn<>("driverAvgModified");
-	@FXML TableColumn<Map, Float> horseAvarageDistanceModifiedColumn = new TableColumn<>("horseAvgDistanceModified");
-	@FXML TableColumn<Map, Float> driverAvarageDistanceModifiedColumn = new TableColumn<>("driverAvgDistanceModified");
-
-	@FXML TableColumn<Map, Float> horseDaysLastRaceColumn = new TableColumn<>("horseDaysLastRace");
-	@FXML TableColumn<Map, Float> driverDaysLastRaceColumn = new TableColumn<>("driverDaysLastRace");
-	@FXML TableColumn<Map, Float> horseDriverDaysLastRaceColumn = new TableColumn<>("bothDaysLastRace");
-
-	@FXML TableColumn<Map, Float> combinedColumn = new TableColumn<>("Custom");
-	@FXML TableColumn<Map, Float> customColumn = new TableColumn<>("Combined");
-
-	@FXML private TableView<Map<String, Object>> racesTable;
-
-	ObservableList<Map<String, Object>> tableRaces;
-	ObservableList<String> raceTypes;
-	private Float driverDivisor;
-	private Float horseDivisor;
-	private Float driverDistanceDivisor;
-	private Float horseDistanceDivisor;
-	private Float customDivisor;
-	private Float combinedDivisor;
-	private float horseWeight;
-	private float driverWeight;
-
-	@Override
-	public void initialize(URL arg0, ResourceBundle arg1) {
-		super.initialize(arg0, arg1);
-
-		horseAvarageWithModifiersColumn.setCellValueFactory(new MapValueFactory<>("horseAvgModified"));
-		driverAvarageWithModifiersColumn.setCellValueFactory(new MapValueFactory<>("driverAvgModified"));
-		customColumn.setCellValueFactory(new MapValueFactory<>("custom"));
-		combinedColumn.setCellValueFactory(new MapValueFactory<Float>("combined"));
-
-		driverAvarageDistanceModifiedColumn.setCellValueFactory(new MapValueFactory<>("driverAvgDistanceModified"));
-		horseAvarageDistanceModifiedColumn.setCellValueFactory(new MapValueFactory<>("horseAvgDistanceModified"));
-
-		horseDaysLastRaceColumn.setCellValueFactory(new MapValueFactory<>("horseDaysLastRace"));
-		driverDaysLastRaceColumn.setCellValueFactory(new MapValueFactory<>("driverDaysLastRace"));
-		horseDriverDaysLastRaceColumn.setCellValueFactory(new MapValueFactory<>("bothDaysLastRace"));
-
-		raceTypes = FXCollections.observableArrayList();
-		raceTypes.addAll(Lists.newArrayList("V75","dd","ld"));
-		raceTypeSelector.setItems(raceTypes);
-
-		datePicker.valueProperty().addListener((observable, oldValue, newValue) -> {
-			if (newValue == null) {
-				getRacesButton.setDisable(true);
-				getRacesForDateButton.setDisable(true);
-				getRaceCalendarButton.setDisable(true);
-			} else if (newValue.isBefore(LocalDate.now())) {
-				getRacesButton.setDisable(false);
-				getRacesForDateButton.setDisable(false);
-				getRaceCalendarButton.setDisable(false);
-			} else if (newValue.isEqual(LocalDate.now())){
-				getRacesButton.setDisable(false);
-				getRacesForDateButton.setDisable(false);
-				getRaceCalendarButton.setDisable(false);
-			} else {
-				//				getRacesButton.setDisable(true);
-				//				getRacesForDateButton.setDisable(true);
-			}
-		});
-
-		getSettings();
-
-	}
-
-	private void getSettings() {
-		final DatabaseController db = DatabaseController.getInstance();
-
-		driverDivisor = Float.parseFloat(db.getSetting("divisorValueDriver"));
-		horseDivisor = Float.parseFloat(db.getSetting("divisorValueHorse"));
-		driverDistanceDivisor = Float.parseFloat(db.getSetting("divisorValueDriverDistance"));
-		horseDistanceDivisor = Float.parseFloat(db.getSetting("divisorValueHorseDistance"));
-		customDivisor = Float.parseFloat(db.getSetting("divisorValueCustom"));
-		combinedDivisor = Float.parseFloat(db.getSetting("divisorValueCombined"));
-
-		horseWeight = Float.parseFloat(db.getSetting("combineHorseWeight"));
-		driverWeight = Float.parseFloat(db.getSetting("combineDriverWeight"));
-	}
-
-	@Override
-	public void updateRacesTable() {
-		final Stopwatch stopWatch = Stopwatch.createStarted();
-		super.updateRacesTable();
-		System.out.println("Super updateTabel took: " + stopWatch.elapsed(TimeUnit.SECONDS) + " seconds");
-
-		todaysRaces.forEach(tr -> {
-			final List<String> distances = todaysRaces.stream()
-					.filter(f -> tr.getRaceNumber() == f.getRaceNumber() && tr.getTrackName().equals(f.getTrackName()))
-					.map(m -> String.valueOf(m.getDistance())).distinct().collect(Collectors.toList());
-			final int i = todaysRaces.indexOf(tr);
-			final Map<String, Object> currentRow = racesTable.getItems().get(i);
-
-			final float laneWinPercent = getLaneWinPercent(tr, Lists.newArrayList(distances), tr.getDistance(), tr.getLane());
-			currentRow.put("horseAvgModified", tr.getAvgHorseTime() - (laneWinPercent / horseDivisor));
-			currentRow.put("driverAvgModified", tr.getAvgDriverTime() - (laneWinPercent / driverDivisor));
-			currentRow.put("horseAvgDistanceModified", tr.getAvgHorseTime() - (laneWinPercent / horseDistanceDivisor));
-			currentRow.put("driverAvgDistanceModified", tr.getAvgDriverTime() - (laneWinPercent / driverDistanceDivisor));
-			currentRow.put("custom", "Not Done"); // tr.getAvgHorseTime() - (laneWinPercent / customDivisor));
-			currentRow.put("combined", ((tr.getAvgHorseTime() - (laneWinPercent / horseDivisor) * horseWeight) +
-					(tr.getAvgDriverTime() - (laneWinPercent / driverDivisor) * driverWeight)) -
-					(laneWinPercent / combinedDivisor));
-
-			currentRow.put("horseDaysLastRace", DatabaseController.getInstance().getLastRaceDaysHorse(tr.getHorseId(), tr.getRaceDate(), tr.getRaceNumber()));
-			final int daysSinceLastRaceDriver = DatabaseController.getInstance().getLastRaceDaysDriver(tr.getDriverId(), tr.getRaceDate(), tr.getRaceNumber());
-			currentRow.put("driverDaysLastRace", daysSinceLastRaceDriver);
-			currentRow.put("bothDaysLastRace", DatabaseController.getInstance().getLastRaceDaysBoth(tr.getHorseId(), tr.getDriverId(), tr.getRaceDate(), tr.getRaceNumber()));
-
-		});
-
-		System.out.println("Other update took " + stopWatch.elapsed(TimeUnit.SECONDS) + " seconds");
-
-		stopWatch.reset().start();
-		normalizeTabel();
-		System.out.println("normalize took " + stopWatch.elapsed(TimeUnit.SECONDS) + " seconds");
-		stopWatch.stop();
-
-	}
-
-	private void normalizeTabel() {
-		final ObservableList<Map<String,Object>> items = racesTable.getItems();
-
-		int i = 0;
-		while (i < items.size()) {
-			final Map<String, Object> firstRow = items.get(i);
-			final List<Map<String, Object>> race = items.stream().filter(p -> p.get("track").equals(firstRow.get("track")) && p.get("race").equals(firstRow.get("race"))).collect(Collectors.toList());
-			normalizeCombined(race);
-			normalizeHorse(race);
-			normalizeHorseDistance(race);
-			normalizeDriver(race);
-			normalizeDriverDistance(race);
-			i += race.size();
-		}
-	}
-
-	private void normalizeCombined(List<Map<String, Object>> race) {
-		try {
-			final List<Float> combinedValues = race.stream().map(m -> ((Float)m.get("combined")).floatValue()).collect(Collectors.toList());
-
-			final double total = combinedValues.stream().mapToDouble(a -> a).sum();
-
-			race.stream().forEach(r -> {
-				final double newValue = (((Float)r.get("combined")).floatValue() / total) * 100;
-				r.put("combined", newValue);
-			});
-		} catch (final ClassCastException e) {
-			System.out.println("WHAT");
-		}
-	}
-
-	private void normalizeHorse(List<Map<String, Object>> race) {
-		try {
-			final List<Float> combinedValues = race.stream().map(m -> ((Float)m.get("horseAvgModified")).floatValue()).collect(Collectors.toList());
-
-			final double total = combinedValues.stream().mapToDouble(a -> a).sum();
-
-			race.stream().forEach(r -> {
-				final double newValue = (((Float)r.get("horseAvgModified")).floatValue() / total) * 100;
-				r.put("horseAvgModified", String.valueOf(newValue));
-			});
-		} catch (final ClassCastException e) {
-			System.out.println("WHAT");
-		}
-	}
-
-	private void normalizeHorseDistance(List<Map<String, Object>> race) {
-		try {
-			final List<Float> combinedValues = race.stream().map(m -> ((Float)m.get("horseAvgDistanceModified")).floatValue()).collect(Collectors.toList());
-
-			final double total = combinedValues.stream().mapToDouble(a -> a).sum();
-
-			race.stream().forEach(r -> {
-				final double newValue = (((Float)r.get("horseAvgDistanceModified")).floatValue() / total) * 100;
-				r.put("horseAvgDistanceModified", String.valueOf(newValue));
-			});
-		} catch (final ClassCastException e) {
-			System.out.println("WHAT");
-		}
-	}
-
-	private void normalizeDriver(List<Map<String, Object>> race) {
-		try {
-			final List<Float> combinedValues = race.stream().map(m -> ((Float)m.get("driverAvgModified")).floatValue()).collect(Collectors.toList());
-
-			final double total = combinedValues.stream().mapToDouble(a -> a).sum();
-
-			race.stream().forEach(r -> {
-				final double newValue = (((Float)r.get("driverAvgModified")).floatValue() / total) * 100;
-				r.put("driverAvgModified", String.valueOf(newValue));
-			});
-		} catch (final ClassCastException e) {
-			System.out.println("WHAT");
-		}
-	}
-
-	private void normalizeDriverDistance(List<Map<String, Object>> race) {
-		try {
-			final List<Float> combinedValues = race.stream().map(m -> ((Float)m.get("driverAvgDistanceModified")).floatValue()).collect(Collectors.toList());
-
-			final double total = combinedValues.stream().mapToDouble(a -> a).sum();
-
-			race.stream().forEach(r -> {
-				final double newValue = (((Float)r.get("driverAvgDistanceModified")).floatValue() / total) * 100;
-				r.put("driverAvgDistanceModified", String.valueOf(newValue));
-			});
-		} catch (final ClassCastException e) {
-			System.out.println("WHAT");
-		}
-	}
-
-
-
-	@FXML
-	public void GetRacesAction() {
-		final Stopwatch createStarted = Stopwatch.createStarted();
-		todaysRaces = DatabaseController.getInstance().getTodaysRaces("", datePicker.getValue().toString(), true);
-		System.out.println("Getting from database took: " + createStarted.elapsed(TimeUnit.SECONDS) + " seconds");
-		updateRacesTable();
-		createStarted.stop();
-		System.out.println("Updateing table took " + createStarted.elapsed(TimeUnit.SECONDS) + " seconds");
-	}
-
-	@FXML
-	public void GetRacesForDate() {
-		//		System.out.println("Getting races for " + raceTypeSelector.getSelectionModel().getSelectedItem() + " at date " + datePicker.getValue().toString());
-		//		resetLaneWinPercentages();
-		//		AtgParser.getInstance().getStartsForDay(datePicker.getValue().toString(), raceTypeSelector.getSelectionModel().getSelectedItem());
-		//		GetRacesAction();
-		getRaceCalendarButton.setDisable(true);
-		getRacesForDateButton.setDisable(true);
-		Platform.runLater(() -> {
-			TravsportParser.getInstance().getRaceCalendar(datePicker.getValue().toString());
-			System.out.println("DONE");
-			getRaceCalendarButton.setDisable(false);
-			getRacesForDateButton.setDisable(false);
-		});
-	}
-
-	public void GetRaceCalendar() {
-		getRaceCalendarButton.setDisable(true);
-		getRacesForDateButton.setDisable(true);
-		Platform.runLater(() -> {
-			TravsportParser.getInstance().getRaceCalendar(null);
-			//		AtgParser.getInstance().getResultsForDate(raceTypeSelector.getSelectionModel().getSelectedItem(), datePicker.getValue().toString());
-			//		GetRacesAction();
-			getRaceCalendarButton.setDisable(false);
-			getRacesForDateButton.setDisable(false);
-		});
-	}
+    @FXML Pane DDButtonPane;
+    @FXML Pane DDResultPane;
+    @FXML DatePicker datePicker;
+    @FXML Button getRacesButton;
+    @FXML Button getRacesForDateButton;
+    @FXML Button getRaceCalendarButton;
+    @FXML ChoiceBox<String> raceTypeSelector;
+
+    @FXML TableColumn<Map, Float> horseAvarageWithModifiersColumn = new TableColumn<>("horseAvgModified");
+    @FXML TableColumn<Map, Float> driverAvarageWithModifiersColumn = new TableColumn<>("driverAvgModified");
+    @FXML TableColumn<Map, Float> horseAvarageDistanceModifiedColumn = new TableColumn<>("horseAvgDistanceModified");
+    @FXML TableColumn<Map, Float> driverAvarageDistanceModifiedColumn = new TableColumn<>("driverAvgDistanceModified");
+
+    @FXML TableColumn<Map, Float> horseDaysLastRaceColumn = new TableColumn<>("horseDaysLastRace");
+    @FXML TableColumn<Map, Float> driverDaysLastRaceColumn = new TableColumn<>("driverDaysLastRace");
+    @FXML TableColumn<Map, Float> horseDriverDaysLastRaceColumn = new TableColumn<>("bothDaysLastRace");
+
+    @FXML TableColumn<Map, Float> combinedColumn = new TableColumn<>("Custom");
+    @FXML TableColumn<Map, Float> customColumn = new TableColumn<>("Combined");
+
+    @FXML private TableView<Map<String, Object>> racesTable;
+
+    ObservableList<Map<String, Object>> tableRaces;
+    ObservableList<String> raceTypes;
+    private Float driverDivisor;
+    private Float horseDivisor;
+    private Float driverDistanceDivisor;
+    private Float horseDistanceDivisor;
+    private Float customDivisor;
+    private Float combinedDivisor;
+    private float horseWeight;
+    private float driverWeight;
+    @FXML CheckBox getFullStatsCheckBox;
+
+    @Override
+    public void initialize(URL arg0, ResourceBundle arg1) {
+        super.initialize(arg0, arg1);
+
+        horseAvarageWithModifiersColumn.setCellValueFactory(new MapValueFactory<>("horseAvgModified"));
+        driverAvarageWithModifiersColumn.setCellValueFactory(new MapValueFactory<>("driverAvgModified"));
+        customColumn.setCellValueFactory(new MapValueFactory<>("custom"));
+        combinedColumn.setCellValueFactory(new MapValueFactory<Float>("combined"));
+
+        driverAvarageDistanceModifiedColumn.setCellValueFactory(new MapValueFactory<>("driverAvgDistanceModified"));
+        horseAvarageDistanceModifiedColumn.setCellValueFactory(new MapValueFactory<>("horseAvgDistanceModified"));
+
+        horseDaysLastRaceColumn.setCellValueFactory(new MapValueFactory<>("horseDaysLastRace"));
+        driverDaysLastRaceColumn.setCellValueFactory(new MapValueFactory<>("driverDaysLastRace"));
+        horseDriverDaysLastRaceColumn.setCellValueFactory(new MapValueFactory<>("bothDaysLastRace"));
+
+        raceTypes = FXCollections.observableArrayList();
+        raceTypes.addAll(Lists.newArrayList("V75", "dd", "ld"));
+        raceTypeSelector.setItems(raceTypes);
+
+        datePicker.valueProperty().addListener((observable, oldValue, newValue) -> {
+            if (newValue == null) {
+                getRacesButton.setDisable(true);
+                getRacesForDateButton.setDisable(true);
+                getRaceCalendarButton.setDisable(true);
+            } else if (newValue.isBefore(LocalDate.now())) {
+                getRacesButton.setDisable(false);
+                getRacesForDateButton.setDisable(false);
+                getRaceCalendarButton.setDisable(false);
+            } else if (newValue.isEqual(LocalDate.now())) {
+                getRacesButton.setDisable(false);
+                getRacesForDateButton.setDisable(false);
+                getRaceCalendarButton.setDisable(false);
+            } else {
+                // getRacesButton.setDisable(true);
+                // getRacesForDateButton.setDisable(true);
+            }
+        });
+
+        getSettings();
+
+    }
+
+    private void getSettings() {
+        final DatabaseController db = DatabaseController.getInstance();
+
+        driverDivisor = Float.parseFloat(db.getSetting("divisorValueDriver"));
+        horseDivisor = Float.parseFloat(db.getSetting("divisorValueHorse"));
+        driverDistanceDivisor = Float.parseFloat(db.getSetting("divisorValueDriverDistance"));
+        horseDistanceDivisor = Float.parseFloat(db.getSetting("divisorValueHorseDistance"));
+        customDivisor = Float.parseFloat(db.getSetting("divisorValueCustom"));
+        combinedDivisor = Float.parseFloat(db.getSetting("divisorValueCombined"));
+
+        horseWeight = Float.parseFloat(db.getSetting("combineHorseWeight"));
+        driverWeight = Float.parseFloat(db.getSetting("combineDriverWeight"));
+    }
+
+    @Override
+    public void updateRacesTable() {
+        final Stopwatch stopWatch = Stopwatch.createStarted();
+        super.updateRacesTable();
+        System.out.println("Super updateTabel took: " + stopWatch.elapsed(TimeUnit.SECONDS) + " seconds");
+
+        todaysRaces.forEach(tr -> {
+            final List<String> distances = todaysRaces.stream()
+                    .filter(f -> tr.getRaceNumber() == f.getRaceNumber() && tr.getTrackName().equals(f.getTrackName()))
+                    .map(m -> String.valueOf(m.getDistance())).distinct().collect(Collectors.toList());
+            final int i = todaysRaces.indexOf(tr);
+            final Map<String, Object> currentRow = racesTable.getItems().get(i);
+
+            final float laneWinPercent = getLaneWinPercent(tr, Lists.newArrayList(distances), tr.getDistance(), tr.getLane());
+            currentRow.put("horseAvgModified", tr.getAvgHorseTime() - (laneWinPercent / horseDivisor));
+            currentRow.put("driverAvgModified", tr.getAvgDriverTime() - (laneWinPercent / driverDivisor));
+            currentRow.put("horseAvgDistanceModified", tr.getAvgHorseTime() - (laneWinPercent / horseDistanceDivisor));
+            currentRow.put("driverAvgDistanceModified", tr.getAvgDriverTime() - (laneWinPercent / driverDistanceDivisor));
+            currentRow.put("custom", "Not Done"); // tr.getAvgHorseTime() - (laneWinPercent / customDivisor));
+            currentRow.put("combined",
+                    ((tr.getAvgHorseTime() - (laneWinPercent / horseDivisor) * horseWeight)
+                            + (tr.getAvgDriverTime() - (laneWinPercent / driverDivisor) * driverWeight))
+                            - (laneWinPercent / combinedDivisor));
+
+            currentRow.put("horseDaysLastRace",
+                    DatabaseController.getInstance().getLastRaceDaysHorse(tr.getHorseId(), tr.getRaceDate(), tr.getRaceNumber()));
+            final int daysSinceLastRaceDriver = DatabaseController.getInstance()
+                    .getLastRaceDaysDriver(tr.getDriverId(), tr.getRaceDate(), tr.getRaceNumber());
+            currentRow.put("driverDaysLastRace", daysSinceLastRaceDriver);
+            currentRow.put("bothDaysLastRace",
+                    DatabaseController.getInstance()
+                            .getLastRaceDaysBoth(tr.getHorseId(), tr.getDriverId(), tr.getRaceDate(), tr.getRaceNumber()));
+
+        });
+
+        System.out.println("Other update took " + stopWatch.elapsed(TimeUnit.SECONDS) + " seconds");
+
+        stopWatch.reset().start();
+        normalizeTabel();
+        System.out.println("normalize took " + stopWatch.elapsed(TimeUnit.SECONDS) + " seconds");
+        stopWatch.stop();
+
+    }
+
+    private void normalizeTabel() {
+        final ObservableList<Map<String, Object>> items = racesTable.getItems();
+
+        int i = 0;
+        while (i < items.size()) {
+            final Map<String, Object> firstRow = items.get(i);
+            final List<Map<String, Object>> race = items.stream()
+                    .filter(p -> p.get("track").equals(firstRow.get("track")) && p.get("race").equals(firstRow.get("race")))
+                    .collect(Collectors.toList());
+            normalizeCombined(race);
+            normalizeHorse(race);
+            normalizeHorseDistance(race);
+            normalizeDriver(race);
+            normalizeDriverDistance(race);
+            i += race.size();
+        }
+    }
+
+    private void normalizeCombined(List<Map<String, Object>> race) {
+        try {
+            final List<Float> combinedValues
+                    = race.stream().map(m -> ((Float) m.get("combined")).floatValue()).collect(Collectors.toList());
+
+            final double total = combinedValues.stream().mapToDouble(a -> a).sum();
+
+            race.stream().forEach(r -> {
+                final double newValue = (((Float) r.get("combined")).floatValue() / total) * 100;
+                r.put("combined", newValue);
+            });
+        } catch (final ClassCastException e) {
+            System.out.println("WHAT");
+        }
+    }
+
+    private void normalizeHorse(List<Map<String, Object>> race) {
+        try {
+            final List<Float> combinedValues
+                    = race.stream().map(m -> ((Float) m.get("horseAvgModified")).floatValue()).collect(Collectors.toList());
+
+            final double total = combinedValues.stream().mapToDouble(a -> a).sum();
+
+            race.stream().forEach(r -> {
+                final double newValue = (((Float) r.get("horseAvgModified")).floatValue() / total) * 100;
+                r.put("horseAvgModified", String.valueOf(newValue));
+            });
+        } catch (final ClassCastException e) {
+            System.out.println("WHAT");
+        }
+    }
+
+    private void normalizeHorseDistance(List<Map<String, Object>> race) {
+        try {
+            final List<Float> combinedValues = race.stream().map(m -> ((Float) m.get("horseAvgDistanceModified")).floatValue())
+                    .collect(Collectors.toList());
+
+            final double total = combinedValues.stream().mapToDouble(a -> a).sum();
+
+            race.stream().forEach(r -> {
+                final double newValue = (((Float) r.get("horseAvgDistanceModified")).floatValue() / total) * 100;
+                r.put("horseAvgDistanceModified", String.valueOf(newValue));
+            });
+        } catch (final ClassCastException e) {
+            System.out.println("WHAT");
+        }
+    }
+
+    private void normalizeDriver(List<Map<String, Object>> race) {
+        try {
+            final List<Float> combinedValues
+                    = race.stream().map(m -> ((Float) m.get("driverAvgModified")).floatValue()).collect(Collectors.toList());
+
+            final double total = combinedValues.stream().mapToDouble(a -> a).sum();
+
+            race.stream().forEach(r -> {
+                final double newValue = (((Float) r.get("driverAvgModified")).floatValue() / total) * 100;
+                r.put("driverAvgModified", String.valueOf(newValue));
+            });
+        } catch (final ClassCastException e) {
+            System.out.println("WHAT");
+        }
+    }
+
+    private void normalizeDriverDistance(List<Map<String, Object>> race) {
+        try {
+            final List<Float> combinedValues = race.stream().map(m -> ((Float) m.get("driverAvgDistanceModified")).floatValue())
+                    .collect(Collectors.toList());
+
+            final double total = combinedValues.stream().mapToDouble(a -> a).sum();
+
+            race.stream().forEach(r -> {
+                final double newValue = (((Float) r.get("driverAvgDistanceModified")).floatValue() / total) * 100;
+                r.put("driverAvgDistanceModified", String.valueOf(newValue));
+            });
+        } catch (final ClassCastException e) {
+            System.out.println("WHAT");
+        }
+    }
+
+    @FXML
+    public void GetRacesAction() {
+        final Stopwatch createStarted = Stopwatch.createStarted();
+        todaysRaces = DatabaseController.getInstance().getTodaysRaces("", datePicker.getValue().toString(), true);
+        System.out.println("Getting from database took: " + createStarted.elapsed(TimeUnit.SECONDS) + " seconds");
+        updateRacesTable();
+        createStarted.stop();
+        System.out.println("Updateing table took " + createStarted.elapsed(TimeUnit.SECONDS) + " seconds");
+    }
+
+    @FXML
+    public void GetRacesForDate() {
+        // System.out.println("Getting races for " +
+        // raceTypeSelector.getSelectionModel().getSelectedItem() + " at date " +
+        // datePicker.getValue().toString());
+        // resetLaneWinPercentages();
+        // AtgParser.getInstance().getStartsForDay(datePicker.getValue().toString(),
+        // raceTypeSelector.getSelectionModel().getSelectedItem());
+        // GetRacesAction();
+        getRaceCalendarButton.setDisable(true);
+        getRacesForDateButton.setDisable(true);
+        Platform.runLater(() -> {
+            TravsportParser.getInstance().getRaceCalendar(datePicker.getValue().toString(), getFullStatsCheckBox.isSelected());
+            System.out.println("DONE");
+            getRaceCalendarButton.setDisable(false);
+            getRacesForDateButton.setDisable(false);
+        });
+    }
+
+    public void GetRaceCalendar() {
+        getRaceCalendarButton.setDisable(true);
+        getRacesForDateButton.setDisable(true);
+        Platform.runLater(() -> {
+            TravsportParser.getInstance().getRaceCalendar(null, false);
+            // AtgParser.getInstance().getResultsForDate(raceTypeSelector.getSelectionModel().getSelectedItem(),
+            // datePicker.getValue().toString());
+            // GetRacesAction();
+            getRaceCalendarButton.setDisable(false);
+            getRacesForDateButton.setDisable(false);
+        });
+    }
 }

+ 0 - 30
ATG/src/fxml/AtgMain.fxml

@@ -46,31 +46,6 @@
                                   <fx:include fx:id="V75Tab" source="V75.fxml" />
                                 </content>
                               </Tab>
-<!--                               <Tab text="V86"> -->
-<!--                                  <content> -->
-<!--                                  	<fx:include fx:id="V86Tab" source="V86.fxml" /> -->
-<!--                                  </content> -->
-<!--                               </Tab> -->
-<!--                               <Tab text="V64"> -->
-<!--                                  <content> -->
-<!--                                     <fx:include fx:id="V64Tab" source="V64.fxml" /> -->
-<!--                                  </content> -->
-<!--                               </Tab> -->
-<!--                               <Tab text="V65"> -->
-<!--                                  <content> -->
-<!--                                     <fx:include fx:id="V65Tab" source="V65.fxml" /> -->
-<!--                                  </content> -->
-<!--                               </Tab> -->
-<!--                               <Tab text="V5"> -->
-<!--                                  <content> -->
-<!--                                     <fx:include fx:id="V5Tab" source="V5.fxml" /> -->
-<!--                                  </content> -->
-<!--                               </Tab> -->
-<!--                               <Tab text="V4"> -->
-<!--                                  <content> -->
-<!--                                     <fx:include fx:id="V4Tab" source="V4.fxml" /> -->
-<!--                                  </content> -->
-<!--                               </Tab> -->
                               <Tab text="TestTab">
                                  <content>
                                     <fx:include fx:id="TestTab" source="TestTab.fxml" />
@@ -92,11 +67,6 @@
                 <fx:include fx:id="TestingTab" source="TestingTab.fxml" />
               </content>
             </Tab>
-            <Tab text="Comparing">
-              <content>
-              	<fx:include fx:id="ComparingTab" source="ComparingTab.fxml" />
-              </content>
-            </Tab>
             <Tab text="NewTab">
             	<content>
             		<fx:include fx:id="NewTab" source="NewTab/NewTab.fxml" />

+ 0 - 19
ATG/src/fxml/ComparingTab.fxml

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.DatePicker?>
-<?import javafx.scene.control.TabPane?>
-<?import javafx.scene.layout.AnchorPane?>
-<?import javafx.scene.layout.FlowPane?>
-
-<AnchorPane prefHeight="800.0" prefWidth="1600.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.ComparingController">
-   <children>
-      <FlowPane nodeOrientation="LEFT_TO_RIGHT" orientation="VERTICAL" prefHeight="30.0" prefWidth="600.0">
-         <children>
-            <DatePicker fx:id="datePicker" />
-            <Button fx:id="submitButton" disable="true" mnemonicParsing="false" onAction="#submitAction" text="Submit" />
-         </children>
-      </FlowPane>
-      <TabPane fx:id="mainComparingTableView" layoutY="30.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="30.0" />
-   </children>
-</AnchorPane>

+ 3 - 1
ATG/src/fxml/TestTab.fxml

@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <?import javafx.scene.control.Button?>
+<?import javafx.scene.control.CheckBox?>
 <?import javafx.scene.control.ChoiceBox?>
 <?import javafx.scene.control.DatePicker?>
 <?import javafx.scene.control.TableColumn?>
@@ -9,7 +10,7 @@
 <?import javafx.scene.layout.BorderPane?>
 <?import javafx.scene.layout.FlowPane?>
 
-<AnchorPane prefHeight="800.0" prefWidth="1600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.TestTabController">
+<AnchorPane prefHeight="800.0" prefWidth="1600.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.TestTabController">
    <children>
       <BorderPane prefHeight="800.0" prefWidth="1600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
          <center>
@@ -53,6 +54,7 @@
                   <ChoiceBox fx:id="raceTypeSelector" prefWidth="150.0" />
                   <Button fx:id="getRacesForDateButton" mnemonicParsing="false" onAction="#GetRacesForDate" text="Parse Races For Date" />
                   <Button fx:id="getRaceCalendarButton" mnemonicParsing="false" onAction="#GetRaceCalendar" text="Get race calendar" />
+                  <CheckBox fx:id="getFullStatsCheckBox" mnemonicParsing="false" text="Get Full Stats" />
                </children>
             </FlowPane>
          </top>

+ 16 - 5
ATG/src/parsers/TravsportParser.java

@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Date;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -28,6 +29,7 @@ import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 
 import controllers.DatabaseController;
+import controllers.MainController;
 
 public class TravsportParser implements Parser {
 
@@ -303,7 +305,7 @@ public class TravsportParser implements Parser {
 
     // Get raceDayResultsJSon
     // https://api.travsport.se/webapi/raceinfo/results/organisation/TROT/sourceofdata/SPORT/racedayid/590412
-    public void getRaceCalendar(String date) {
+    public void getRaceCalendar(String date, boolean getFullStats) {
         // JSON för race dagen
         // https://api.travsport.se/webapi/raceinfo/startlists/organisation/TROT/sourceofdata/SPORT/racedayid/590412
         // JSON för calendern
@@ -399,14 +401,12 @@ public class TravsportParser implements Parser {
                                 "",
                                 raceDayId);
                         final int horseIdByName = databaseController.getHorseId(horseName, horseTravsportId);
-                        final int horseRaceCount = databaseController.getRaceCount("Horse", horseIdByName);
-                        if (horseIdByName > -1 && horseRaceCount <= 5) {
+                        if (horseIdByName > -1 && shouldUpdateFullStats(getFullStats, "horse", horseTravsportId)) {
                             getHorseStatByIdJson(horseTravsportId, horseName, "", -1);
                         }
 
                         final int driverIdByName = databaseController.getDriverId(driverName, driverId);
-                        final int driverRaceCount = databaseController.getRaceCount("Driver", driverIdByName);
-                        if (driverIdByName > -1 && driverRaceCount <= 20) {
+                        if (driverIdByName > -1 && shouldUpdateFullStats(getFullStats, "driver", driverId)) {
                             getDriverStatById(driverId, driverName, -1);
                         }
                     }
@@ -425,6 +425,12 @@ public class TravsportParser implements Parser {
 
     }
 
+    private boolean shouldUpdateFullStats(boolean getFullStats, String who, int travsportId) {
+        final String collected = DatabaseController.getInstance().getFullStatsCollected(who, travsportId);
+
+        return getFullStats && (Strings.isNullOrEmpty(collected) || collected.equalsIgnoreCase("null"));
+    }
+
     public int getHorseIdByName(String horseName) {
         /*
          * Uppdatera med detta anrop, kommer tillbaka en JSON sträng som man kan ta utan
@@ -571,6 +577,8 @@ public class TravsportParser implements Parser {
                     raceId);
 
         }
+        databaseController
+                .setfullStatsCollected("horse", horseTravsportId, MainController.DATE_FORMAT.format(new Date()).toString());
     }
 
     public void getDriverStatById(int driverTravsportId, String driverName, int raceId) {
@@ -649,6 +657,9 @@ public class TravsportParser implements Parser {
 
             }
 
+            databaseController
+                    .setfullStatsCollected("driver", driverTravsportId, MainController.DATE_FORMAT.format(new Date()).toString());
+
         } catch (FailingHttpStatusCodeException | IOException e) {
             throw new RuntimeException(e.getMessage(), e);
         }