refactor: newest delivery from main
This commit is contained in:
commit
00e4bb03f4
32 changed files with 722 additions and 881 deletions
|
|
@ -34,21 +34,25 @@
|
||||||
<artifactId>jersey-client</artifactId>
|
<artifactId>jersey-client</artifactId>
|
||||||
<version>${version.jersey}</version>
|
<version>${version.jersey}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.inject</groupId>
|
<groupId>org.glassfish.jersey.inject</groupId>
|
||||||
<artifactId>jersey-hk2</artifactId>
|
<artifactId>jersey-hk2</artifactId>
|
||||||
<version>${version.jersey}</version>
|
<version>${version.jersey}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.media</groupId>
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
<artifactId>jersey-media-json-jackson</artifactId>
|
<artifactId>jersey-media-json-jackson</artifactId>
|
||||||
<version>${version.jersey}</version>
|
<version>${version.jersey}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.activation</groupId>
|
<groupId>jakarta.activation</groupId>
|
||||||
<artifactId>jakarta.activation-api</artifactId>
|
<artifactId>jakarta.activation-api</artifactId>
|
||||||
<version>2.1.3</version>
|
<version>2.1.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.inject</groupId>
|
<groupId>com.google.inject</groupId>
|
||||||
<artifactId>guice</artifactId>
|
<artifactId>guice</artifactId>
|
||||||
|
|
@ -61,11 +65,13 @@
|
||||||
<artifactId>javafx-fxml</artifactId>
|
<artifactId>javafx-fxml</artifactId>
|
||||||
<version>${version.jfx}</version>
|
<version>${version.jfx}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-controls</artifactId>
|
<artifactId>javafx-controls</artifactId>
|
||||||
<version>${version.jfx}</version>
|
<version>${version.jfx}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-web</artifactId>
|
<artifactId>javafx-web</artifactId>
|
||||||
|
|
@ -91,6 +97,27 @@
|
||||||
<version>${version.mockito}</version>
|
<version>${version.mockito}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- websockets -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-messaging</artifactId>
|
||||||
|
<version>6.2.12</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.glassfish.tyrus.bundles/tyrus-standalone-client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.tyrus.bundles</groupId>
|
||||||
|
<artifactId>tyrus-standalone-client</artifactId>
|
||||||
|
<version>2.2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-websocket</artifactId>
|
||||||
|
<version>6.2.12</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,18 @@ package client;
|
||||||
import client.scenes.FoodpalApplicationCtrl;
|
import client.scenes.FoodpalApplicationCtrl;
|
||||||
import client.scenes.recipe.IngredientListCtrl;
|
import client.scenes.recipe.IngredientListCtrl;
|
||||||
import client.scenes.recipe.RecipeStepListCtrl;
|
import client.scenes.recipe.RecipeStepListCtrl;
|
||||||
|
import client.utils.ConfigService;
|
||||||
import client.utils.LocaleManager;
|
import client.utils.LocaleManager;
|
||||||
|
import client.utils.ServerUtils;
|
||||||
|
import client.utils.WebSocketUtils;
|
||||||
import com.google.inject.Binder;
|
import com.google.inject.Binder;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
|
|
||||||
import client.scenes.MainCtrl;
|
import client.scenes.MainCtrl;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public class MyModule implements Module {
|
public class MyModule implements Module {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -33,6 +38,12 @@ public class MyModule implements Module {
|
||||||
binder.bind(FoodpalApplicationCtrl.class).in(Scopes.SINGLETON);
|
binder.bind(FoodpalApplicationCtrl.class).in(Scopes.SINGLETON);
|
||||||
binder.bind(IngredientListCtrl.class).in(Scopes.SINGLETON);
|
binder.bind(IngredientListCtrl.class).in(Scopes.SINGLETON);
|
||||||
binder.bind(RecipeStepListCtrl.class).in(Scopes.SINGLETON);
|
binder.bind(RecipeStepListCtrl.class).in(Scopes.SINGLETON);
|
||||||
|
|
||||||
binder.bind(LocaleManager.class).in(Scopes.SINGLETON);
|
binder.bind(LocaleManager.class).in(Scopes.SINGLETON);
|
||||||
|
binder.bind(ServerUtils.class).in(Scopes.SINGLETON);
|
||||||
|
binder.bind(WebSocketUtils.class).in(Scopes.SINGLETON);
|
||||||
|
|
||||||
|
binder.bind(ConfigService.class).toInstance(new ConfigService(Path.of("config.json")));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,17 +9,22 @@ import client.exception.UpdateException;
|
||||||
import client.scenes.recipe.IngredientListCtrl;
|
import client.scenes.recipe.IngredientListCtrl;
|
||||||
import client.scenes.recipe.RecipeStepListCtrl;
|
import client.scenes.recipe.RecipeStepListCtrl;
|
||||||
|
|
||||||
|
import client.utils.Config;
|
||||||
|
import client.utils.ConfigService;
|
||||||
import client.utils.DefaultRecipeFactory;
|
import client.utils.DefaultRecipeFactory;
|
||||||
import client.utils.LocaleAware;
|
import client.utils.LocaleAware;
|
||||||
import client.utils.LocaleManager;
|
import client.utils.LocaleManager;
|
||||||
import client.utils.ServerUtils;
|
import client.utils.ServerUtils;
|
||||||
|
import client.utils.WebSocketUtils;
|
||||||
import commons.Recipe;
|
import commons.Recipe;
|
||||||
|
|
||||||
|
import commons.ws.Topics;
|
||||||
|
import commons.ws.messages.Message;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ListCell;
|
import javafx.scene.control.ListCell;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
|
|
@ -31,6 +36,7 @@ import javafx.scene.text.Font;
|
||||||
|
|
||||||
public class FoodpalApplicationCtrl implements LocaleAware {
|
public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
private final ServerUtils server;
|
private final ServerUtils server;
|
||||||
|
private final WebSocketUtils webSocketUtils;
|
||||||
private final LocaleManager localeManager;
|
private final LocaleManager localeManager;
|
||||||
private final IngredientListCtrl ingredientListCtrl;
|
private final IngredientListCtrl ingredientListCtrl;
|
||||||
private final RecipeStepListCtrl stepListCtrl;
|
private final RecipeStepListCtrl stepListCtrl;
|
||||||
|
|
@ -41,10 +47,9 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
// everything in the left lane
|
// everything in the left lane
|
||||||
@FXML
|
@FXML
|
||||||
public Label recipesLabel;
|
public Label recipesLabel;
|
||||||
public ComboBox<String> langSelectMenu;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ListView<Recipe> recipeList;
|
public ListView<Recipe> recipeList;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button addRecipeButton;
|
private Button addRecipeButton;
|
||||||
|
|
@ -55,6 +60,13 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
@FXML
|
@FXML
|
||||||
public Button cloneRecipeButton;
|
public Button cloneRecipeButton;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button favouriteButton;
|
||||||
|
|
||||||
|
private Config config;
|
||||||
|
private final ConfigService configService;
|
||||||
|
|
||||||
|
|
||||||
// === CENTER: RECIPE DETAILS ===
|
// === CENTER: RECIPE DETAILS ===
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
|
@ -69,14 +81,20 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
@Inject
|
@Inject
|
||||||
public FoodpalApplicationCtrl(
|
public FoodpalApplicationCtrl(
|
||||||
ServerUtils server,
|
ServerUtils server,
|
||||||
|
WebSocketUtils webSocketUtils,
|
||||||
LocaleManager localeManager,
|
LocaleManager localeManager,
|
||||||
IngredientListCtrl ingredientListCtrl,
|
IngredientListCtrl ingredientListCtrl,
|
||||||
RecipeStepListCtrl stepListCtrl
|
RecipeStepListCtrl stepListCtrl,
|
||||||
|
ConfigService configService
|
||||||
) {
|
) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
this.webSocketUtils = webSocketUtils;
|
||||||
this.localeManager = localeManager;
|
this.localeManager = localeManager;
|
||||||
this.ingredientListCtrl = ingredientListCtrl;
|
this.ingredientListCtrl = ingredientListCtrl;
|
||||||
this.stepListCtrl = stepListCtrl;
|
this.stepListCtrl = stepListCtrl;
|
||||||
|
this.configService = configService;
|
||||||
|
|
||||||
|
initializeWebSocket();
|
||||||
}
|
}
|
||||||
private void initRecipeList() {
|
private void initRecipeList() {
|
||||||
// Show recipe name in the list
|
// Show recipe name in the list
|
||||||
|
|
@ -87,10 +105,12 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
setText(empty || item == null ? "" : item.getName());
|
setText(empty || item == null ? "" : item.getName());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// When your selection changes, update details in the panel
|
// When your selection changes, update details in the panel
|
||||||
recipeList.getSelectionModel().selectedItemProperty().addListener(
|
recipeList.getSelectionModel().selectedItemProperty().addListener(
|
||||||
(obs, oldRecipe, newRecipe) -> showRecipeDetails(newRecipe)
|
(obs, oldRecipe, newRecipe) -> {
|
||||||
|
showRecipeDetails(newRecipe);
|
||||||
|
updateFavouriteButton(newRecipe);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Double-click to go to detail screen
|
// Double-click to go to detail screen
|
||||||
|
|
@ -101,6 +121,27 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
private void initializeWebSocket() {
|
||||||
|
webSocketUtils.connect(() -> {
|
||||||
|
webSocketUtils.subscribe(Topics.RECIPES, (Message _) -> {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
Recipe selectedRecipe = recipeList.getSelectionModel().getSelectedItem();
|
||||||
|
refresh(); // refresh the left list
|
||||||
|
if (selectedRecipe == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// select last selected recipe if it still exists, first otherwise (done by refresh())
|
||||||
|
Recipe recipeInList = recipeList.getItems().stream()
|
||||||
|
.filter(r -> r.getId().equals(selectedRecipe.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
showRecipeDetails(recipeInList);
|
||||||
|
}); // runLater as it's on another non-FX thread.
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
private void initStepsIngredientsList() {
|
private void initStepsIngredientsList() {
|
||||||
// Initialize callback for ingredient list updates
|
// Initialize callback for ingredient list updates
|
||||||
this.ingredientListCtrl.setUpdateCallback(newList -> {
|
this.ingredientListCtrl.setUpdateCallback(newList -> {
|
||||||
|
|
@ -134,12 +175,14 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void initializeComponents() {
|
public void initializeComponents() {
|
||||||
// TODO Reduce code duplication??
|
config = configService.getConfig();
|
||||||
|
|
||||||
initStepsIngredientsList();
|
initStepsIngredientsList();
|
||||||
initRecipeList();
|
initRecipeList();
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
|
updateFavouriteButton(recipeList.getSelectionModel().getSelectedItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showName(String name) {
|
private void showName(String name) {
|
||||||
final int NAME_FONT_SIZE = 20;
|
final int NAME_FONT_SIZE = 20;
|
||||||
editableTitleArea.getChildren().clear();
|
editableTitleArea.getChildren().clear();
|
||||||
|
|
@ -147,6 +190,7 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
nameLabel.setFont(new Font("System Bold", NAME_FONT_SIZE));
|
nameLabel.setFont(new Font("System Bold", NAME_FONT_SIZE));
|
||||||
editableTitleArea.getChildren().add(nameLabel);
|
editableTitleArea.getChildren().add(nameLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateText() {
|
public void updateText() {
|
||||||
addRecipeButton.setText(getLocaleString("menu.button.add.recipe"));
|
addRecipeButton.setText(getLocaleString("menu.button.add.recipe"));
|
||||||
|
|
@ -158,13 +202,6 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
printRecipeButton.setText(getLocaleString("menu.button.print"));
|
printRecipeButton.setText(getLocaleString("menu.button.print"));
|
||||||
|
|
||||||
recipesLabel.setText(getLocaleString("menu.label.recipes"));
|
recipesLabel.setText(getLocaleString("menu.label.recipes"));
|
||||||
|
|
||||||
// TODO propagate ResourceBundle lang changes to nested controller
|
|
||||||
// ingredientsLabel.setText(getLocaleString("menu.label.ingredients"));
|
|
||||||
// preparationLabel.setText(getLocaleString("menu.label.preparation"));
|
|
||||||
|
|
||||||
// addIngredientButton.setText(getLocaleString("menu.button.add.ingredient"));
|
|
||||||
// addPreparationStepButton.setText(getLocaleString("menu.button.add.step"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -200,11 +237,13 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
}
|
}
|
||||||
detailsScreen.visibleProperty().set(!recipes.isEmpty());
|
detailsScreen.visibleProperty().set(!recipes.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printError(String msg) {
|
private void printError(String msg) {
|
||||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
alert.setContentText(msg);
|
alert.setContentText(msg);
|
||||||
alert.showAndWait();
|
alert.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a recipe, by providing a default name "Untitled recipe (n)".
|
* Adds a recipe, by providing a default name "Untitled recipe (n)".
|
||||||
* The UX flow is now:
|
* The UX flow is now:
|
||||||
|
|
@ -277,7 +316,7 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
try {
|
try {
|
||||||
server.updateRecipe(selected);
|
server.updateRecipe(selected);
|
||||||
refresh();
|
refresh();
|
||||||
recipeList.getSelectionModel().select(selected);
|
//recipeList.getSelectionModel().select(selected);
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
// throw a nice blanket UpdateException
|
// throw a nice blanket UpdateException
|
||||||
throw new UpdateException("Error occurred when updating recipe name!");
|
throw new UpdateException("Error occurred when updating recipe name!");
|
||||||
|
|
@ -287,7 +326,6 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
editableTitleArea.getChildren().add(edit);
|
editableTitleArea.getChildren().add(edit);
|
||||||
edit.requestFocus();
|
edit.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void makePrintable() {
|
private void makePrintable() {
|
||||||
System.out.println("Recipe printed");
|
System.out.println("Recipe printed");
|
||||||
|
|
@ -307,6 +345,39 @@ public class FoodpalApplicationCtrl implements LocaleAware {
|
||||||
recipeList.getSelectionModel().select(cloned);
|
recipeList.getSelectionModel().select(cloned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateFavouriteButton(Recipe recipe) {
|
||||||
|
if (recipe == null) {
|
||||||
|
favouriteButton.setDisable(true);
|
||||||
|
favouriteButton.setText("☆");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
favouriteButton.setDisable(false);
|
||||||
|
favouriteButton.setText(
|
||||||
|
config.isFavourite(recipe.getId()) ? "★" : "☆"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private void toggleFavourite() {
|
||||||
|
Recipe selected = recipeList.getSelectionModel().getSelectedItem();
|
||||||
|
if (selected == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long id = selected.getId();
|
||||||
|
|
||||||
|
if (config.isFavourite(id)) {
|
||||||
|
config.removeFavourite(id);
|
||||||
|
} else {
|
||||||
|
config.addFavourite(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
configService.save();
|
||||||
|
updateFavouriteButton(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package client.scenes.nutrition;
|
||||||
|
|
||||||
|
import client.utils.LocaleAware;
|
||||||
|
import client.utils.LocaleManager;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
|
||||||
|
public class NutritionDetailsCtrl implements LocaleAware {
|
||||||
|
private final LocaleManager manager;
|
||||||
|
|
||||||
|
public Label ingredientName;
|
||||||
|
public Label fatInputLabel;
|
||||||
|
public Label proteinInputLabel;
|
||||||
|
public Label carbInputLabel;
|
||||||
|
public Label estimatedKcalLabel;
|
||||||
|
public Label usageLabel;
|
||||||
|
|
||||||
|
public TextField fatInputElement;
|
||||||
|
public TextField proteinInputElement;
|
||||||
|
public TextField carbInputElement;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NutritionDetailsCtrl(
|
||||||
|
LocaleManager manager
|
||||||
|
) {
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void updateText() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LocaleManager getLocaleManager() {
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package client.scenes.nutrition;
|
||||||
|
|
||||||
|
import client.scenes.FoodpalApplicationCtrl;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import commons.Recipe;
|
||||||
|
import javafx.collections.ListChangeListener;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.control.ListView;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class NutritionViewCtrl {
|
||||||
|
private ObservableList<Recipe> recipes;
|
||||||
|
private HashMap<String, Integer> ingredientStats;
|
||||||
|
public ListView<String> nutritionIngredientsView;
|
||||||
|
private final NutritionDetailsCtrl nutritionDetailsCtrl;
|
||||||
|
|
||||||
|
// TODO into Ingredient class definition
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comedically verbose function to count unique appearances of an ingredient by name in each recipe.
|
||||||
|
* For each recipe:
|
||||||
|
* 1. Collect unique ingredients that appeared in that recipe.
|
||||||
|
* 2. For each unique ingredient in said recipe:
|
||||||
|
* 1. Initialize the appearance for that ingredient to 0.
|
||||||
|
* 2. For each recipe in list:
|
||||||
|
* 1. If the name of the ingredient exists in the recipe list, increment the statistic by 1.
|
||||||
|
* 2. Else maintain the same value for that statistic.
|
||||||
|
* @param recipeList
|
||||||
|
*/
|
||||||
|
private void updateIngredientStats(
|
||||||
|
List<Recipe> recipeList
|
||||||
|
) {
|
||||||
|
recipeList.forEach(recipe -> {
|
||||||
|
Set<String> uniqueIngredients = new HashSet<>(recipe.getIngredients());
|
||||||
|
nutritionIngredientsView.getItems().setAll(uniqueIngredients);
|
||||||
|
uniqueIngredients.forEach(ingredient -> {
|
||||||
|
ingredientStats.put(ingredient, 0);
|
||||||
|
recipeList.forEach(r ->
|
||||||
|
ingredientStats.put(
|
||||||
|
ingredient,
|
||||||
|
ingredientStats.get(ingredient) + (
|
||||||
|
(r.getIngredients().contains(ingredient))
|
||||||
|
? 1 : 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Inject
|
||||||
|
public NutritionViewCtrl(
|
||||||
|
FoodpalApplicationCtrl foodpalApplicationCtrl,
|
||||||
|
NutritionDetailsCtrl nutritionDetailsCtrl
|
||||||
|
) {
|
||||||
|
this.recipes = foodpalApplicationCtrl.recipeList.getItems();
|
||||||
|
this.recipes.addListener((ListChangeListener<? super Recipe>) _ -> {
|
||||||
|
updateIngredientStats(this.recipes);
|
||||||
|
});
|
||||||
|
this.nutritionDetailsCtrl = nutritionDetailsCtrl;
|
||||||
|
this.nutritionIngredientsView.selectionModelProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,8 @@ public class Config {
|
||||||
private List<Long> favourites = new ArrayList<>();
|
private List<Long> favourites = new ArrayList<>();
|
||||||
private List<String> shoppingList = new ArrayList<>();
|
private List<String> shoppingList = new ArrayList<>();
|
||||||
|
|
||||||
public Config(){}
|
public Config() {
|
||||||
|
}
|
||||||
|
|
||||||
public String getLanguage() {
|
public String getLanguage() {
|
||||||
return language;
|
return language;
|
||||||
|
|
@ -22,10 +23,6 @@ public class Config {
|
||||||
return shoppingList;
|
return shoppingList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> getFavourites() {
|
|
||||||
return favourites;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getServerUrl() {
|
public String getServerUrl() {
|
||||||
return serverUrl;
|
return serverUrl;
|
||||||
}
|
}
|
||||||
|
|
@ -45,4 +42,29 @@ public class Config {
|
||||||
public void setShoppingList(List<String> shoppingList) {
|
public void setShoppingList(List<String> shoppingList) {
|
||||||
this.shoppingList = shoppingList;
|
this.shoppingList = shoppingList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// favourite helper
|
||||||
|
|
||||||
|
public List<Long> getFavourites() {
|
||||||
|
if (favourites == null) {
|
||||||
|
favourites = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
return favourites;
|
||||||
|
}
|
||||||
|
// to avoid null pointers.
|
||||||
|
|
||||||
|
public boolean isFavourite(long recipeId) {
|
||||||
|
return getFavourites().contains(recipeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFavourite(long recipeId) {
|
||||||
|
if (!getFavourites().contains(recipeId)) {
|
||||||
|
getFavourites().add(recipeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeFavourite(long recipeId) {
|
||||||
|
getFavourites().remove(recipeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Delft University of Technology
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package client.utils;
|
|
||||||
|
|
||||||
import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
|
|
||||||
|
|
||||||
import java.net.ConnectException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import jakarta.ws.rs.core.GenericType;
|
|
||||||
import org.glassfish.jersey.client.ClientConfig;
|
|
||||||
|
|
||||||
import commons.Quote;
|
|
||||||
import jakarta.ws.rs.ProcessingException;
|
|
||||||
import jakarta.ws.rs.client.ClientBuilder;
|
|
||||||
import jakarta.ws.rs.client.Entity;
|
|
||||||
|
|
||||||
public class ServerUtilsExample {
|
|
||||||
|
|
||||||
private static final String SERVER = "http://localhost:8080/";
|
|
||||||
|
|
||||||
// public void getQuotesTheHardWay() throws IOException, URISyntaxException {
|
|
||||||
// var url = new URI("http://localhost:8080/api/quotes").toURL();
|
|
||||||
// var is = url.openConnection().getInputStream();
|
|
||||||
// var br = new BufferedReader(new InputStreamReader(is));
|
|
||||||
// String line;
|
|
||||||
// while ((line = br.readLine()) != null) {
|
|
||||||
// System.out.println(line);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public List<Quote> getQuotes() {
|
|
||||||
return ClientBuilder.newClient(new ClientConfig()) //
|
|
||||||
.target(SERVER).path("api/quotes") //
|
|
||||||
.request(APPLICATION_JSON) //
|
|
||||||
.get(new GenericType<List<Quote>>() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Quote addQuote(Quote quote) {
|
|
||||||
return ClientBuilder.newClient(new ClientConfig()) //
|
|
||||||
.target(SERVER).path("api/quotes") //
|
|
||||||
.request(APPLICATION_JSON) //
|
|
||||||
.post(Entity.entity(quote, APPLICATION_JSON), Quote.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isServerAvailable() {
|
|
||||||
try {
|
|
||||||
ClientBuilder.newClient(new ClientConfig()) //
|
|
||||||
.target(SERVER) //
|
|
||||||
.request(APPLICATION_JSON) //
|
|
||||||
.get();
|
|
||||||
} catch (ProcessingException e) {
|
|
||||||
if (e.getCause() instanceof ConnectException) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
111
client/src/main/java/client/utils/WebSocketUtils.java
Normal file
111
client/src/main/java/client/utils/WebSocketUtils.java
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
package client.utils;
|
||||||
|
|
||||||
|
import commons.ws.messages.Message;
|
||||||
|
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
|
||||||
|
import org.springframework.messaging.simp.stomp.StompSession;
|
||||||
|
import org.springframework.messaging.simp.stomp.StompHeaders;
|
||||||
|
import org.springframework.messaging.simp.stomp.StompCommand;
|
||||||
|
import org.springframework.messaging.simp.stomp.StompFrameHandler;
|
||||||
|
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
|
||||||
|
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
||||||
|
import org.springframework.web.socket.messaging.WebSocketStompClient;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class WebSocketUtils {
|
||||||
|
private static final String WS_URL = "ws://localhost:8080/updates";
|
||||||
|
private WebSocketStompClient stompClient;
|
||||||
|
private StompSession stompSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the websocket server.
|
||||||
|
* @param onConnected OnConnected callback
|
||||||
|
*/
|
||||||
|
public void connect(@Nullable Runnable onConnected) {
|
||||||
|
StandardWebSocketClient webSocketClient = new StandardWebSocketClient(); // Create WS Client
|
||||||
|
|
||||||
|
stompClient = new WebSocketStompClient(webSocketClient);
|
||||||
|
stompClient.setMessageConverter(new MappingJackson2MessageConverter()); // Use jackson
|
||||||
|
|
||||||
|
CompletableFuture<StompSession> sessionFuture = stompClient.connectAsync(
|
||||||
|
WS_URL,
|
||||||
|
new StompSessionHandlerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
|
||||||
|
stompSession = session;
|
||||||
|
System.out.println("WebSocket connected: " + session.getSessionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleException(StompSession session, @Nullable StompCommand command,
|
||||||
|
StompHeaders headers, byte[] payload,
|
||||||
|
Throwable exception) {
|
||||||
|
System.err.println("STOMP error: " + exception.getMessage());
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleTransportError(StompSession session, Throwable exception) {
|
||||||
|
System.err.println("STOMP transport error: " + exception.getMessage());
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
sessionFuture.thenAccept(session -> {
|
||||||
|
stompSession = session;
|
||||||
|
System.out.println("Connection successful, session ready");
|
||||||
|
if (onConnected != null) {
|
||||||
|
onConnected.run();
|
||||||
|
}
|
||||||
|
}).exceptionally(throwable -> {
|
||||||
|
System.err.println("Failed to connect: " + throwable.getMessage());
|
||||||
|
throwable.printStackTrace();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe to a topic.
|
||||||
|
* @param destination Destination to subscribe to, for example: /subscribe/recipe
|
||||||
|
* @param messageHandler Handler for received messages
|
||||||
|
*/
|
||||||
|
public void subscribe(String destination, Consumer<Message> messageHandler) {
|
||||||
|
if (stompSession == null || !stompSession.isConnected()) {
|
||||||
|
System.err.println("Cannot subscribe - not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stompSession.subscribe(destination, new StompFrameHandler() {
|
||||||
|
@Override
|
||||||
|
public Type getPayloadType(StompHeaders headers) {
|
||||||
|
return Message.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleFrame(StompHeaders headers, @Nullable Object payload) {
|
||||||
|
Message message = (Message) payload;
|
||||||
|
messageHandler.accept(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
System.out.println("Subscribed to: " + destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
if (stompSession != null && stompSession.isConnected()) {
|
||||||
|
stompSession.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stompClient != null) {
|
||||||
|
stompClient.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnected() {
|
||||||
|
return stompSession != null && stompSession.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
<Button fx:id="editRecipeTitleButton" onAction="#editRecipeTitle" text="Edit" />
|
<Button fx:id="editRecipeTitleButton" onAction="#editRecipeTitle" text="Edit" />
|
||||||
<Button fx:id="removeRecipeButton2" mnemonicParsing="false" onAction="#removeSelectedRecipe" text="Remove Recipe" />
|
<Button fx:id="removeRecipeButton2" mnemonicParsing="false" onAction="#removeSelectedRecipe" text="Remove Recipe" />
|
||||||
<Button fx:id="printRecipeButton" mnemonicParsing="false" onAction="#makePrintable" text="Print Recipe" />
|
<Button fx:id="printRecipeButton" mnemonicParsing="false" onAction="#makePrintable" text="Print Recipe" />
|
||||||
|
<Button fx:id="favouriteButton" onAction="#toggleFavourite" text="☆" />
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
||||||
<!-- Ingredients -->
|
<!-- Ingredients -->
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import java.lang.*?>
|
||||||
|
<?import java.util.*?>
|
||||||
|
<?import javafx.scene.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
|
||||||
|
<?import javafx.scene.shape.Line?>
|
||||||
|
<AnchorPane xmlns="http://javafx.com/javafx"
|
||||||
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
|
fx:controller="client.scenes.nutrition.NutritionDetailsCtrl"
|
||||||
|
prefHeight="400.0" prefWidth="600.0">
|
||||||
|
<VBox visible="false">
|
||||||
|
<Label fx:id="ingredientName" />
|
||||||
|
<HBox>
|
||||||
|
<Label fx:id="fatInputLabel">Fat: </Label>
|
||||||
|
<TextField fx:id="fatInputElement" />
|
||||||
|
</HBox>
|
||||||
|
<HBox>
|
||||||
|
<Label fx:id="proteinInputLabel">Protein: </Label>
|
||||||
|
<TextField fx:id="proteinInputElement" />
|
||||||
|
</HBox>
|
||||||
|
<HBox>
|
||||||
|
<Label fx:id="carbInputLabel">Carbohydrates: </Label>
|
||||||
|
<TextField fx:id="carbInputElement" />
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="estimatedKcalLabel">Estimated: 0kcal</Label>
|
||||||
|
<Label fx:id="usageLabel">Not used in any recipes</Label>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
</AnchorPane>
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import java.lang.*?>
|
||||||
|
<?import java.util.*?>
|
||||||
|
<?import javafx.scene.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
|
||||||
|
<AnchorPane xmlns="http://javafx.com/javafx"
|
||||||
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
|
fx:controller="client.scenes.nutrition.NutritionViewCtrl"
|
||||||
|
prefHeight="400.0" prefWidth="600.0">
|
||||||
|
<SplitPane>
|
||||||
|
<ListView fx:id="nutritionIngredientsView" />
|
||||||
|
<AnchorPane>
|
||||||
|
<fx:include source="NutritionDetails.fxml" />
|
||||||
|
</AnchorPane>
|
||||||
|
</SplitPane>
|
||||||
|
</AnchorPane>
|
||||||
|
|
@ -45,6 +45,12 @@
|
||||||
<version>${version.mockito}</version>
|
<version>${version.mockito}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.20.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Delft University of Technology
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package commons;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.builder.ToStringStyle.MULTI_LINE_STYLE;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.GenerationType;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Person {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
public long id;
|
|
||||||
|
|
||||||
public String firstName;
|
|
||||||
public String lastName;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private Person() {
|
|
||||||
// for object mapper
|
|
||||||
}
|
|
||||||
|
|
||||||
public Person(String firstName, String lastName) {
|
|
||||||
this.firstName = firstName;
|
|
||||||
this.lastName = lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return EqualsBuilder.reflectionEquals(this, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return HashCodeBuilder.reflectionHashCode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return ToStringBuilder.reflectionToString(this, MULTI_LINE_STYLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Delft University of Technology
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package commons;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.builder.ToStringStyle.MULTI_LINE_STYLE;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
||||||
|
|
||||||
import jakarta.persistence.CascadeType;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
|
||||||
import jakarta.persistence.GenerationType;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.OneToOne;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Quote {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
public long id;
|
|
||||||
|
|
||||||
@OneToOne(cascade = CascadeType.PERSIST)
|
|
||||||
public Person person;
|
|
||||||
public String quote;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private Quote() {
|
|
||||||
// for object mappers
|
|
||||||
}
|
|
||||||
|
|
||||||
public Quote(Person person, String quote) {
|
|
||||||
this.person = person;
|
|
||||||
this.quote = quote;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
return EqualsBuilder.reflectionEquals(this, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return HashCodeBuilder.reflectionHashCode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return ToStringBuilder.reflectionToString(this, MULTI_LINE_STYLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,6 +10,8 @@ import commons.Ingredient;
|
||||||
public class CreateIngredientMessage implements Message {
|
public class CreateIngredientMessage implements Message {
|
||||||
private Ingredient ingredient;
|
private Ingredient ingredient;
|
||||||
|
|
||||||
|
public CreateIngredientMessage() {} // for jackson
|
||||||
|
|
||||||
public CreateIngredientMessage(Ingredient ingredient) {
|
public CreateIngredientMessage(Ingredient ingredient) {
|
||||||
this.ingredient = ingredient;
|
this.ingredient = ingredient;
|
||||||
}
|
}
|
||||||
|
|
@ -27,4 +29,9 @@ public class CreateIngredientMessage implements Message {
|
||||||
public Ingredient getIngredient() {
|
public Ingredient getIngredient() {
|
||||||
return ingredient;
|
return ingredient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for jackson
|
||||||
|
public void setIngredient(Ingredient ingredient) {
|
||||||
|
this.ingredient = ingredient;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import commons.Recipe;
|
||||||
public class CreateRecipeMessage implements Message {
|
public class CreateRecipeMessage implements Message {
|
||||||
private Recipe recipe;
|
private Recipe recipe;
|
||||||
|
|
||||||
|
public CreateRecipeMessage() {} // for jackson
|
||||||
|
|
||||||
public CreateRecipeMessage(Recipe recipe) {
|
public CreateRecipeMessage(Recipe recipe) {
|
||||||
this.recipe = recipe;
|
this.recipe = recipe;
|
||||||
}
|
}
|
||||||
|
|
@ -27,4 +29,9 @@ public class CreateRecipeMessage implements Message {
|
||||||
public Recipe getRecipe() {
|
public Recipe getRecipe() {
|
||||||
return recipe;
|
return recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for jackson
|
||||||
|
public void setRecipe(Recipe recipe) {
|
||||||
|
this.recipe = recipe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ package commons.ws.messages;
|
||||||
public class DeleteIngredientMessage implements Message {
|
public class DeleteIngredientMessage implements Message {
|
||||||
private Long ingredientId;
|
private Long ingredientId;
|
||||||
|
|
||||||
|
public DeleteIngredientMessage() {} // for jackson
|
||||||
|
|
||||||
public DeleteIngredientMessage(Long ingredientId) {
|
public DeleteIngredientMessage(Long ingredientId) {
|
||||||
this.ingredientId = ingredientId;
|
this.ingredientId = ingredientId;
|
||||||
}
|
}
|
||||||
|
|
@ -25,4 +27,9 @@ public class DeleteIngredientMessage implements Message {
|
||||||
public Long getIngredientId() {
|
public Long getIngredientId() {
|
||||||
return ingredientId;
|
return ingredientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for jackson
|
||||||
|
public void setIngredientId(Long ingredientId) {
|
||||||
|
this.ingredientId = ingredientId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ package commons.ws.messages;
|
||||||
public class DeleteRecipeMessage implements Message {
|
public class DeleteRecipeMessage implements Message {
|
||||||
private Long recipeId;
|
private Long recipeId;
|
||||||
|
|
||||||
|
public DeleteRecipeMessage() {} // for jackson
|
||||||
|
|
||||||
public DeleteRecipeMessage(Long recipeId) {
|
public DeleteRecipeMessage(Long recipeId) {
|
||||||
this.recipeId = recipeId;
|
this.recipeId = recipeId;
|
||||||
}
|
}
|
||||||
|
|
@ -25,4 +27,9 @@ public class DeleteRecipeMessage implements Message {
|
||||||
public Long getRecipeId() {
|
public Long getRecipeId() {
|
||||||
return recipeId;
|
return recipeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for jackson
|
||||||
|
public void setRecipeId(Long recipeId) {
|
||||||
|
this.recipeId = recipeId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package commons.ws.messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message sent when a recipe becomes a favourite.
|
||||||
|
* @see commons.ws.messages.Message.Type#RECIPE_FAVOURITE
|
||||||
|
*/
|
||||||
|
public class FavouriteRecipeMessage implements Message{
|
||||||
|
|
||||||
|
private Long recipeId;
|
||||||
|
|
||||||
|
public FavouriteRecipeMessage(Long recipeId) {
|
||||||
|
this.recipeId = recipeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return Type.RECIPE_FAVOURITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the ID of the recipe that got favourite.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Long getRecipeId() {
|
||||||
|
return recipeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,21 @@
|
||||||
package commons.ws.messages;
|
package commons.ws.messages;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
|
||||||
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "type"
|
||||||
|
)
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = CreateRecipeMessage.class, name = "RECIPE_CREATE"),
|
||||||
|
@JsonSubTypes.Type(value = UpdateRecipeMessage.class, name = "RECIPE_UPDATE"),
|
||||||
|
@JsonSubTypes.Type(value = DeleteRecipeMessage.class, name = "RECIPE_DELETE"),
|
||||||
|
@JsonSubTypes.Type(value = CreateIngredientMessage.class, name = "INGREDIENT_CREATE"),
|
||||||
|
@JsonSubTypes.Type(value = UpdateIngredientMessage.class, name = "INGREDIENT_UPDATE"),
|
||||||
|
@JsonSubTypes.Type(value = DeleteIngredientMessage.class, name = "INGREDIENT_DELETE")
|
||||||
|
})
|
||||||
public interface Message {
|
public interface Message {
|
||||||
public enum Type {
|
public enum Type {
|
||||||
/**
|
/**
|
||||||
|
|
@ -23,6 +39,15 @@ public interface Message {
|
||||||
*/
|
*/
|
||||||
RECIPE_DELETE,
|
RECIPE_DELETE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message sent when a recipe became a favourite.
|
||||||
|
*
|
||||||
|
* @see commons.ws.messages.FavouriteRecipeMessage
|
||||||
|
*/
|
||||||
|
|
||||||
|
RECIPE_FAVOURITE,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message sent when a new ingredient is created.
|
* Message sent when a new ingredient is created.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue