Merge branch 'prevent-server-dependancy' into 'main'
added a Dialog sequence for when the server is not up Closes #58 See merge request cse1105/2025-2026/teams/csep-team-76!79
This commit is contained in:
commit
76852fcd4f
4 changed files with 208 additions and 9 deletions
|
|
@ -2,6 +2,7 @@ package client;
|
||||||
|
|
||||||
import client.scenes.FoodpalApplicationCtrl;
|
import client.scenes.FoodpalApplicationCtrl;
|
||||||
import client.scenes.MainCtrl;
|
import client.scenes.MainCtrl;
|
||||||
|
import client.scenes.ServerConnectionDialogCtrl;
|
||||||
import client.utils.server.ServerUtils;
|
import client.utils.server.ServerUtils;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
|
@ -27,10 +28,15 @@ public class UI extends Application {
|
||||||
|
|
||||||
var serverUtils = INJECTOR.getInstance(ServerUtils.class);
|
var serverUtils = INJECTOR.getInstance(ServerUtils.class);
|
||||||
if (!serverUtils.isServerAvailable()) {
|
if (!serverUtils.isServerAvailable()) {
|
||||||
var msg = "Server needs to be started before the client, but it does not seem to be available. Shutting down.";
|
var connectionHandler = INJECTOR.getInstance(ServerConnectionDialogCtrl.class);
|
||||||
System.err.println(msg);
|
boolean serverConnected = connectionHandler.promptForURL();
|
||||||
|
|
||||||
|
if(!serverConnected){
|
||||||
|
var msg = "User Cancelled Server connection. Shutting down";
|
||||||
|
System.err.print(msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var foodpal = FXML.load(FoodpalApplicationCtrl.class, "client", "scenes", "FoodpalApplication.fxml");
|
var foodpal = FXML.load(FoodpalApplicationCtrl.class, "client", "scenes", "FoodpalApplication.fxml");
|
||||||
|
|
||||||
var mainCtrl = INJECTOR.getInstance(MainCtrl.class);
|
var mainCtrl = INJECTOR.getInstance(MainCtrl.class);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
package client.scenes;
|
||||||
|
|
||||||
|
|
||||||
|
import client.utils.ConfigService;
|
||||||
|
import client.utils.server.ServerUtils;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.TextInputDialog;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
||||||
|
public class ServerConnectionDialogCtrl {
|
||||||
|
|
||||||
|
private final ConfigService configService;
|
||||||
|
private final ServerUtils serverUtils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ServerConnectionDialogCtrl(ConfigService configService, ServerUtils serverUtils) {
|
||||||
|
this.configService = configService;
|
||||||
|
this.serverUtils = serverUtils;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return a boolean for if the user got connected to server or
|
||||||
|
*/
|
||||||
|
public boolean promptForURL(){
|
||||||
|
Alert error = new Alert(Alert.AlertType.ERROR); //creates an error alert
|
||||||
|
error.setTitle("Server is Unavailable");
|
||||||
|
error.setHeaderText("Unable to connect to Server");
|
||||||
|
error.setContentText("The server at " + configService.getConfig().getServerUrl()
|
||||||
|
+ " is not available\n\n Would you like to try a different Server URL?");
|
||||||
|
|
||||||
|
error.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
|
||||||
|
Optional<ButtonType> userChoice = error.showAndWait(); //asks if user wants to input server URL
|
||||||
|
|
||||||
|
if(userChoice.isEmpty() || userChoice.get() == ButtonType.NO){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true){ // Keeps asking the user until either a valid url is provided or the user exits
|
||||||
|
TextInputDialog dialog =
|
||||||
|
new TextInputDialog(configService.getConfig().getServerUrl());
|
||||||
|
dialog.setTitle("Enter new server URL");
|
||||||
|
dialog.setContentText("Server URL:");
|
||||||
|
Optional<String> userRes = dialog.showAndWait();
|
||||||
|
if(userRes.isEmpty()){
|
||||||
|
return false; //user cancelled the operation
|
||||||
|
}
|
||||||
|
String newServer = userRes.get().trim();
|
||||||
|
|
||||||
|
if(newServer.isEmpty()){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.WARNING);
|
||||||
|
alert.setTitle("Invalid Input");
|
||||||
|
alert.setHeaderText("Invalid server URL");
|
||||||
|
alert.setContentText("Please enter a valid URL");
|
||||||
|
alert.showAndWait();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
configService.getConfig().setServerUrl(newServer);
|
||||||
|
if(serverUtils.isServerAvailable()){
|
||||||
|
configService.save();
|
||||||
|
Alert success = new Alert(Alert.AlertType.INFORMATION);
|
||||||
|
success.setTitle("Success");
|
||||||
|
success.setHeaderText("Connected to Server");
|
||||||
|
success.setContentText("Successfully connected to the server!");
|
||||||
|
success.showAndWait();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Alert retry = new Alert(Alert.AlertType.ERROR);
|
||||||
|
retry.setTitle("Failed");
|
||||||
|
retry.setHeaderText("Failed to connect to Server");
|
||||||
|
retry.setContentText("Would you like to try another URL?");
|
||||||
|
retry.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
|
||||||
|
Optional<ButtonType> result = retry.showAndWait();
|
||||||
|
if(result.isEmpty() || result.get() == ButtonType.NO){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,13 +7,11 @@ import com.google.inject.Inject;
|
||||||
import commons.Ingredient;
|
import commons.Ingredient;
|
||||||
import commons.Recipe;
|
import commons.Recipe;
|
||||||
import commons.RecipeIngredient;
|
import commons.RecipeIngredient;
|
||||||
import jakarta.ws.rs.ProcessingException;
|
|
||||||
import jakarta.ws.rs.client.ClientBuilder;
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
import org.glassfish.jersey.client.ClientConfig;
|
import org.glassfish.jersey.client.ClientConfig;
|
||||||
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ConnectException;
|
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
|
|
@ -171,10 +169,9 @@ public class ServerUtils {
|
||||||
.target(this.endpoints.baseUrl()) //
|
.target(this.endpoints.baseUrl()) //
|
||||||
.request(APPLICATION_JSON) //
|
.request(APPLICATION_JSON) //
|
||||||
.get();
|
.get();
|
||||||
} catch (ProcessingException e) {
|
|
||||||
if (e.getCause() instanceof ConnectException) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
catch(Exception e){
|
||||||
|
return false; //any exception caught will return false, not just processing exception.
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
102
locc.sh
Normal file
102
locc.sh
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -u
|
||||||
|
|
||||||
|
# 1. Check for git repo
|
||||||
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
echo "Error: current directory is not a git repository." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Define path patterns
|
||||||
|
PATH_CLIENT='client/src/**/*.java'
|
||||||
|
PATH_SERVER='server/src/**/*.java'
|
||||||
|
PATH_COMMONS='commons/src/**/*.java'
|
||||||
|
PATH_PROD='*/src/main/*.java'
|
||||||
|
PATH_TEST='*/src/test/*.java'
|
||||||
|
PATH_ALL='*.java'
|
||||||
|
|
||||||
|
# 3. Helper functions
|
||||||
|
|
||||||
|
# Standard count: Includes imports, respects WS changes
|
||||||
|
count_lines_standard() {
|
||||||
|
git show --format="" --patch "$1" -- "$2" \
|
||||||
|
| grep -E '^\+[^+/][^/]+$' \
|
||||||
|
| grep -v '+ *[*@]' \
|
||||||
|
| wc -l
|
||||||
|
}
|
||||||
|
|
||||||
|
# Strict count: Ignores imports, ignores pure WS changes
|
||||||
|
count_lines_strict() {
|
||||||
|
git show --format="" --patch -w "$1" -- "$2" \
|
||||||
|
| grep -E '^\+[^+/][^/]+$' \
|
||||||
|
| grep -v 'import' \
|
||||||
|
| grep -v '+ *[*@]' \
|
||||||
|
| wc -l
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Analyzing commits on 'main'..." >&2
|
||||||
|
|
||||||
|
# 4. Main Loop
|
||||||
|
# Use %ae for Author Email
|
||||||
|
git log --no-merges --pretty=format:'%H %ae' main | {
|
||||||
|
|
||||||
|
declare -A client_count
|
||||||
|
declare -A server_count
|
||||||
|
declare -A commons_count
|
||||||
|
declare -A prod_count
|
||||||
|
declare -A test_count
|
||||||
|
declare -A total_count
|
||||||
|
declare -A strict_count
|
||||||
|
declare -A seen_users
|
||||||
|
|
||||||
|
while read -r hash raw_email; do
|
||||||
|
# Normalize email to lowercase
|
||||||
|
email=$(echo "$raw_email" | tr '[:upper:]' '[:lower:]')
|
||||||
|
seen_users["$email"]=1
|
||||||
|
|
||||||
|
# Run counts (Standard)
|
||||||
|
c_add=$(count_lines_standard "$hash" "$PATH_CLIENT")
|
||||||
|
s_add=$(count_lines_standard "$hash" "$PATH_SERVER")
|
||||||
|
k_add=$(count_lines_standard "$hash" "$PATH_COMMONS")
|
||||||
|
p_add=$(count_lines_standard "$hash" "$PATH_PROD")
|
||||||
|
t_add=$(count_lines_standard "$hash" "$PATH_TEST")
|
||||||
|
all_add=$(count_lines_standard "$hash" "$PATH_ALL")
|
||||||
|
|
||||||
|
# Run count (Strict)
|
||||||
|
strict_add=$(count_lines_strict "$hash" "$PATH_ALL")
|
||||||
|
|
||||||
|
# Accumulate
|
||||||
|
client_count["$email"]=$(( ${client_count["$email"]:-0} + c_add ))
|
||||||
|
server_count["$email"]=$(( ${server_count["$email"]:-0} + s_add ))
|
||||||
|
commons_count["$email"]=$(( ${commons_count["$email"]:-0} + k_add ))
|
||||||
|
prod_count["$email"]=$(( ${prod_count["$email"]:-0} + p_add ))
|
||||||
|
test_count["$email"]=$(( ${test_count["$email"]:-0} + t_add ))
|
||||||
|
total_count["$email"]=$(( ${total_count["$email"]:-0} + all_add ))
|
||||||
|
strict_count["$email"]=$(( ${strict_count["$email"]:-0} + strict_add ))
|
||||||
|
|
||||||
|
printf "." >&2
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "" >&2
|
||||||
|
echo "Done." >&2
|
||||||
|
|
||||||
|
# 5. Print Table
|
||||||
|
# Widths: Email=40, Others=10, Strict=13
|
||||||
|
printf "%-40s | %-10s | %-10s | %-10s | %-10s | %-10s | %-10s | %-13s\n" \
|
||||||
|
"User Email" "Client" "Server" "Commons" "Prod" "Test" "Total" "Total (Strict)"
|
||||||
|
printf "%s\n" "-----------------------------------------|------------|------------|------------|------------|------------|------------|----------------"
|
||||||
|
|
||||||
|
for email in "${!seen_users[@]}"; do
|
||||||
|
echo "$email"
|
||||||
|
done | sort | while read -r e; do
|
||||||
|
printf "%-40s | %-10d | %-10d | %-10d | %-10d | %-10d | %-10d | %-13d\n" \
|
||||||
|
"$e" \
|
||||||
|
"${client_count[$e]:-0}" \
|
||||||
|
"${server_count[$e]:-0}" \
|
||||||
|
"${commons_count[$e]:-0}" \
|
||||||
|
"${prod_count[$e]:-0}" \
|
||||||
|
"${test_count[$e]:-0}" \
|
||||||
|
"${total_count[$e]:-0}" \
|
||||||
|
"${strict_count[$e]:-0}"
|
||||||
|
done
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue