Browse Source

orphanRemoval for Matches, Refactoring

master
GAM 4 years ago
parent
commit
bfbbfb56d7
3 changed files with 112 additions and 67 deletions
  1. +1
    -1
      src/main/java/app/data/entity/Match.java
  2. +1
    -1
      src/main/java/app/views/match/MatchView.java
  3. +110
    -65
      src/main/java/app/views/match/components/MatchComponent.java

+ 1
- 1
src/main/java/app/data/entity/Match.java View File

@ -37,7 +37,7 @@ public class Match {
return Objects.hash(id);
}
@OneToMany(mappedBy = "match", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@OneToMany(mappedBy = "match", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
public Collection<Game> getGames() {
return games;
}


+ 1
- 1
src/main/java/app/views/match/MatchView.java View File

@ -43,7 +43,7 @@ public class MatchView extends NavigationViewBase {
////////////
private void configureLayout() {
matchComponent = new MatchComponent(navigation, chessComService, navigation.getMatchService(), gameService, gameInfoService, gameImageService);
matchComponent = new MatchComponent(navigation, chessComService, gameImageService);
add(matchComponent);
}


+ 110
- 65
src/main/java/app/views/match/components/MatchComponent.java View File

@ -4,8 +4,6 @@ import app.data.bean.CalculatedMatch;
import app.data.entity.Game;
import app.data.entity.Match;
import app.data.service.ChessComService;
import app.data.service.GameInfoService;
import app.data.service.GameService;
import app.data.service.MatchService;
import app.gameimage.GameImageService;
import app.navigation.Navigation;
@ -13,6 +11,8 @@ import app.utils.ChessComUtils;
import app.utils.EntityComponentUtils;
import app.utils.StringUtils;
import app.views.navigation.interfaces.ContentConfigurable;
import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
@ -39,8 +39,6 @@ public class MatchComponent extends Div implements ContentConfigurable {
private final Navigation navigation;
private final ChessComService chessComService;
private final MatchService matchService;
private final GameService gameService;
private final GameInfoService gameInfoService;
private final GameImageService gameImageService;
private final VerticalLayout headerLayout = new VerticalLayout();
@ -63,23 +61,19 @@ public class MatchComponent extends Div implements ContentConfigurable {
private final Button chessComButton = new Button("Autofill with the latest 6 games between the players", new Icon(VaadinIcon.MAGIC));
private Registration chessComButtonButtonRegistration;
private Match match;
private CalculatedMatch calculatedMatch;
public MatchComponent(Navigation navigation,
@Autowired ChessComService chessComService,
@Autowired MatchService matchService, // TODO: get this stuff from navigation instead, or even better: Do it like PaussHFramework
@Autowired GameService gameService,
@Autowired GameInfoService gameInfoService,
@Autowired GameImageService gameImageService) {
this.navigation = navigation;
this.chessComService = chessComService;
this.matchService = matchService;
this.gameService = gameService;
this.gameInfoService = gameInfoService;
this.matchService = navigation.getMatchService();
this.gameImageService = gameImageService;
add(headerLayout);
defineHeaderLayout();
defineGamesLayout();
defineNoGamesLayout();
@ -87,15 +81,22 @@ public class MatchComponent extends Div implements ContentConfigurable {
}
private void defineNoGamesLayout() {
Label label = new Label("No games for this match in the database.");
noGamesLayout.add(createNoGamesLabel(), createAddGamesButton());
noGamesLayout.setAlignItems(FlexComponent.Alignment.CENTER);
}
private Label createNoGamesLabel() {
return new Label("No games for this match in the database.");
}
private Button createAddGamesButton() {
Button button = new Button("Add games", new Icon(VaadinIcon.PLUS));
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
button.addClickListener(event -> {
navigation.setEditFlag(true);
remove(noGamesLayout);
});
noGamesLayout.add(label, button);
noGamesLayout.setAlignItems(FlexComponent.Alignment.CENTER);
return button;
}
private void defineHeaderLayout() {
@ -113,16 +114,28 @@ public class MatchComponent extends Div implements ContentConfigurable {
}
private void defineEditLayout() {
defineEditLayoutWrapper();
defineEditLayoutItself();
defineEditLayoutTextFields();
defineEditSubmitButton();
addButtonsToEditLayout();
}
private void defineEditLayoutWrapper() {
editLayoutWrapper.add(editLayout);
editLayoutWrapper.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
}
private void defineEditLayoutItself() {
editLayout.setAlignItems(FlexComponent.Alignment.CENTER);
editLayout.setWidth("");
editLayout.addClassName("wrapper");
editLayout.add(chessComButton);
}
private void defineEditLayoutTextFields() {
for (int i = 0; i < 6; i++) {
TextField textField = new TextField();
textField.setWidth("23em");
@ -132,9 +145,12 @@ public class MatchComponent extends Div implements ContentConfigurable {
editLayout.add(horizontalLayout);
editTextFields.add(textField);
}
}
private void defineEditSubmitButton() {
editSubmitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
}
private void addButtonsToEditLayout() {
HorizontalLayout buttonLayout = new HorizontalLayout();
buttonLayout.setAlignItems(FlexComponent.Alignment.CENTER);
buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
@ -145,68 +161,116 @@ public class MatchComponent extends Div implements ContentConfigurable {
@Override
public void configureContent() {
try {
Match match = navigation.getSelectedMatch().orElseThrow();
configureHeaderContent(match);
configureMainContent(match);
match = navigation.getSelectedMatch().orElseThrow();
calculatedMatch = matchService.getCalculatedMatch(match);
configureHeaderContent();
configureMainContent();
} catch (NoSuchElementException e) {
gamesLayout.removeAll();
add(navigation.getValidationLabel());
}
}
private void configureMainContent(Match match) {
private void configureHeaderContent() {
configureHeaderPlayersLayout();
configureHeaderResultLabel();
}
private void configureHeaderPlayersLayout() {
HorizontalLayout player1 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer1());
HorizontalLayout player2 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer2());
Label vs = new Label("vs.");
headerPlayersLayout.removeAll();
headerPlayersLayout.add(player1, vs, player2);
}
private void configureHeaderResultLabel() {
if (match.getGames().isEmpty() || navigation.editFlag()) {
headerLayout.remove(headerResultLabel);
} else {
headerLayout.add(headerResultLabel);
headerResultLabel.setText(String.format("%s",
StringUtils.getResultString("-", calculatedMatch.getScore1(), calculatedMatch.getScore2())));
}
}
private void configureMainContent() {
if (navigation.editFlag()) {
remove(gamesLayout);
add(editLayoutWrapper);
configureEditContent(match);
configureEditContent();
return;
}
remove(editLayoutWrapper);
configureGamesContent(match);
configureGamesContent();
}
private void configureEditContent(Match match) {
private void configureEditContent() {
List<Game> games = new ArrayList<>(match.getGames());
// clear text fields
for (TextField textField : editTextFields) {
textField.setValue("");
}
// fill text fields;
clearTextFields();
fillTextFieldsWithURLs(games);
configureChessComButton();
configureEditSubmitButton();
configureEditCancelButton();
}
private void clearTextFields() {
editTextFields.forEach(textField -> textField.setValue(""));
}
private void fillTextFieldsWithURLs(List<Game> games) {
for (int i = 0; i < Math.min(games.size(), 6); i++)
editTextFields.get(i).setValue(ChessComUtils.getGameURL(games.get(i)));
}
private void configureChessComButton() {
if (chessComButtonButtonRegistration != null) chessComButtonButtonRegistration.remove();
chessComButtonButtonRegistration = chessComButton.addClickListener(event -> {
ProgressBar progressBar = new ProgressBar();
progressBar.setIndeterminate(true);
editLayout.add(progressBar);
chessComButtonButtonRegistration = chessComButton.addClickListener(createChessComButtonClickListener());
}
private ComponentEventListener<ClickEvent<Button>> createChessComButtonClickListener() {
return event -> {
List<Game> gamesBetweenPlayers = chessComService.getLatestGamesBetweenPlayers(match, 6, 2);
for (int i = 0; i < Math.min(gamesBetweenPlayers.size(), 6); i++) {
editTextFields.get(i).setValue(ChessComUtils.getGameURL(gamesBetweenPlayers.get(i)));
}
editLayout.remove(progressBar);
});
fillTextFieldsWithURLs(gamesBetweenPlayers);
};
}
private void configureEditSubmitButton() {
if (editSubmitButtonRegistration != null) editSubmitButtonRegistration.remove();
editSubmitButtonRegistration = editSubmitButton.addClickListener(event -> {
match.getGames().clear(); // TODO: delete old games from database as well
for (TextField textField : editTextFields) {
Optional<Game> game = chessComService.getGame(textField.getValue(), match); // TODO: handle this when Optional is empty!
game.ifPresent(value -> match.getGames().add(value));
}
editSubmitButtonRegistration = editSubmitButton.addClickListener(createEditSubmitButtonClickListener());
}
private ComponentEventListener<ClickEvent<Button>> createEditSubmitButtonClickListener() {
return event -> {
match.getGames().clear();
addGamesToMatchFromFieldValues();
matchService.update(match);
match.getGames().forEach(gameImageService::createImageIfNotPresent);
navigation.setEditFlag(false);
});
};
}
private void addGamesToMatchFromFieldValues() {
for (TextField textField : editTextFields) {
Optional<Game> game = chessComService.getGame(textField.getValue(), match); // TODO: handle this when Optional is empty!
game.ifPresent(value -> match.getGames().add(value));
}
}
private void configureEditCancelButton() {
if (editCancelButtonRegistration != null) editCancelButtonRegistration.remove();
editCancelButtonRegistration = editCancelButton.addClickListener(event ->
UI.getCurrent().navigate(String.format("matchday/%s", navigation.getWildcardParam().replace("edit/", ""))));
editCancelButtonRegistration = editCancelButton.addClickListener(createEditCancelButtonListener());
}
private ComponentEventListener<ClickEvent<Button>> createEditCancelButtonListener() {
return event -> UI.getCurrent().navigate(String.format("matchday/%s", navigation.getWildcardParam().replace("edit/", "")));
}
private void configureGamesContent(Match match) {
private void configureGamesContent() {
if (match.getGames().isEmpty()) {
remove(gamesLayout);
add(noGamesLayout);
@ -221,23 +285,4 @@ public class MatchComponent extends Div implements ContentConfigurable {
gamesLayout.add(new GameComponent(game, gameImageService));
}
}
private void configureHeaderContent(Match match) {
CalculatedMatch calculatedMatch = navigation.getMatchService().getCalculatedMatch(match);
HorizontalLayout player1 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer1());
HorizontalLayout player2 = EntityComponentUtils.getPlayerLabel(calculatedMatch.getPlayer2());
Label vs = new Label("vs.");
headerPlayersLayout.removeAll();
headerPlayersLayout.add(player1, vs, player2);
if (match.getGames().isEmpty() || navigation.editFlag()) {
headerLayout.remove(headerResultLabel);
} else {
headerLayout.add(headerResultLabel);
headerResultLabel.setText(String.format("%s",
StringUtils.getResultString("-", calculatedMatch.getScore1(), calculatedMatch.getScore2())));
}
}
}

Loading…
Cancel
Save