diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetCompetitorInLeaderboardAction.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetCompetitorInLeaderboardAction.java index a5cfd3fd5d0..2d5583674f1 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetCompetitorInLeaderboardAction.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/actions/GetCompetitorInLeaderboardAction.java @@ -1,9 +1,13 @@ package com.sap.sailing.dashboards.gwt.client.actions; +import java.util.List; + import com.google.gwt.core.shared.GwtIncompatible; import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardAction; import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext; import com.sap.sailing.dashboards.gwt.shared.dto.LeaderboardCompetitorsDTO; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException; @@ -29,7 +33,9 @@ public class GetCompetitorInLeaderboardAction implements DashboardAction competitorsFromBestToWorst = lb.getCompetitorsFromBestToWorst(MillisecondsTimePoint.now()); + List competitorDTOs = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorWithoutBoatDTOListTemp(competitorsFromBestToWorst); + result.setCompetitors(competitorDTOs); return result; } } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionListener.java index b4ec20fdf25..5e281844e23 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionListener.java @@ -1,8 +1,8 @@ package com.sap.sailing.dashboards.gwt.client.popups.competitorselection; -import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; public interface CompetitorSelectionListener { - public void didClickOKWithSelectedCompetitor(CompetitorDTO competitor); + public void didClickOKWithSelectedCompetitor(CompetitorWithoutBoatDTO competitor); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java index 743eb998187..84a1612c221 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/CompetitorSelectionPopup.java @@ -16,7 +16,7 @@ import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.table.CompetitorTable; import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.table.CompetitorTableRowSelectionListener; import com.sap.sailing.dashboards.gwt.client.widgets.ActionPanel; -import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; public class CompetitorSelectionPopup extends Composite implements HasWidgets, CompetitorTableRowSelectionListener { @@ -38,7 +38,7 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C @UiField(provided = true) ActionPanel okButton; - private CompetitorDTO currentCompetitorSelected; + private CompetitorWithoutBoatDTO currentCompetitorSelected; private boolean isVisible; private CompetitorSelectionPopupResources competitorSelectionPopupResources = CompetitorSelectionPopupResources.INSTANCE; @@ -63,7 +63,7 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C okButton.getElement().setInnerText("OK"); } - public void show(List competitorList) { + public void show(List competitorList) { competitortable.setTableContent(competitorList); RootLayoutPanel.get().add(this); competitorselectionpopup.addStyleName(competitorSelectionPopupResources.gss().popupshow()); @@ -88,7 +88,7 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C this.competitorSelectionPopupListener.remove(o); } - public void notifyListenerAboutOKButtonClickedWithSelectedCompetitorName(CompetitorDTO competitor) { + public void notifyListenerAboutOKButtonClickedWithSelectedCompetitorName(CompetitorWithoutBoatDTO competitor) { for (CompetitorSelectionListener newStartAnalysisListener : competitorSelectionPopupListener) { newStartAnalysisListener.didClickOKWithSelectedCompetitor(competitor); } @@ -127,7 +127,7 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C } @Override - public void didSelectedRowWithCompetitorName(CompetitorDTO competitor) { + public void didSelectedRowWithCompetitorName(CompetitorWithoutBoatDTO competitor) { currentCompetitorSelected = competitor; } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTable.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTable.java index 56ae2e648c1..cf23b175868 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTable.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTable.java @@ -10,46 +10,46 @@ import com.google.gwt.user.cellview.client.TextColumn; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SingleSelectionModel; -import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sse.gwt.client.celltable.BaseCelltable; public class CompetitorTable extends AbsolutePanel { - private CellTable table; + private CellTable table; private CompetitorTableRowSelectionListener competitorTableRowSelectionListener; public CompetitorTable(CompetitorTableRowSelectionListener competitorTableRowSelectionListener) { this.competitorTableRowSelectionListener = competitorTableRowSelectionListener; } - public void setTableContent(List competitorNames) { + public void setTableContent(List competitorNames) { if (table == null) { initTable(competitorNames); } } - private void initTable(List competitorNames) { + private void initTable(List competitorNames) { CellTable.Resources tableRes = GWT.create(CompetitorTableStyleResource.class); - table = new BaseCelltable(15, tableRes); + table = new BaseCelltable(15, tableRes); table.getElement().getStyle().setWidth(100, Unit.PCT); table.setSkipRowHoverStyleUpdate(true); table.setSkipRowHoverCheck(true); table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); - final SingleSelectionModel selectionModel = new SingleSelectionModel(); + final SingleSelectionModel selectionModel = new SingleSelectionModel(); table.setSelectionModel(selectionModel); selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { public void onSelectionChange(SelectionChangeEvent event) { - CompetitorDTO selected = selectionModel.getSelectedObject(); + CompetitorWithoutBoatDTO selected = selectionModel.getSelectedObject(); if (selected != null) { competitorTableRowSelectionListener.didSelectedRowWithCompetitorName(selected); } } }); - TextColumn competitorNameCollumn = new TextColumn() { + TextColumn competitorNameCollumn = new TextColumn() { @Override - public String getValue(CompetitorDTO competitor) { + public String getValue(CompetitorWithoutBoatDTO competitor) { return competitor.getName(); } }; diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTableRowSelectionListener.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTableRowSelectionListener.java index 3087d8745b4..c2d3907f45e 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTableRowSelectionListener.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/popups/competitorselection/table/CompetitorTableRowSelectionListener.java @@ -1,8 +1,8 @@ package com.sap.sailing.dashboards.gwt.client.popups.competitorselection.table; -import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; public interface CompetitorTableRowSelectionListener { - public void didSelectedRowWithCompetitorName(CompetitorDTO competitor); + public void didSelectedRowWithCompetitorName(CompetitorWithoutBoatDTO competitor); } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java index b808797b761..c3952e6b90c 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/client/widgets/startanalysis/StartAnalysisWidget.java @@ -41,6 +41,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.LeaderboardCompetitorsDTO; import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysesDTO; import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources; @@ -240,7 +241,7 @@ public class StartAnalysisWidget extends Composite implements HasWidgets, PollsL competitorSelectionPopup.addListener(new CompetitorSelectionListener() { @Override - public void didClickOKWithSelectedCompetitor(CompetitorDTO competitor) { + public void didClickOKWithSelectedCompetitor(CompetitorWithoutBoatDTO competitor) { if (competitor != null) { Cookies.removeCookie(cookieKeyForSelectedCompetitorInLeaderboard); Cookies.setCookie(cookieKeyForSelectedCompetitorInLeaderboard, competitor.getIdAsString(), new Date(new Date().getTime()+SELECTED_COMPETITOR_ID_COOKIE_KEY_EXPIRE_TIME_IN_MILLIS)); diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/util/actions/startanalysis/StartAnalysisDTOFactory.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/util/actions/startanalysis/StartAnalysisDTOFactory.java index b5d6940aac2..e6709ea5637 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/util/actions/startanalysis/StartAnalysisDTOFactory.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/server/util/actions/startanalysis/StartAnalysisDTOFactory.java @@ -15,6 +15,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO; import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisRankingTableEntryDTO; import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO; import com.sap.sailing.dashboards.gwt.shared.dto.WindAndAdvantagesInfoForStartLineDTO; +import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.common.LegType; @@ -59,7 +60,8 @@ public final class StartAnalysisDTOFactory extends AbstractStartAnalysisCreation competitors.add(createStartAnalysisCompetitorDTO(dashboardDispatchContext, trackedRace, rankOfCompetitorWhilePassingSecondWaypoint, competitor)); } if (competitor != null) { - startAnalysisDTO.competitor = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore().convertToCompetitorDTO(competitor); + Boat boatOfCompetitor = trackedRace.getBoatOfCompetitor(competitor); + startAnalysisDTO.competitor = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore().convertToCompetitorDTO(competitor, boatOfCompetitor); logger.log(Level.INFO, "Created startanalysis for competitor"+competitor); } startAnalysisDTO.startAnalysisCompetitorDTOs = competitors; @@ -191,8 +193,9 @@ public final class StartAnalysisDTOFactory extends AbstractStartAnalysisCreation private static StartAnalysisCompetitorDTO createStartAnalysisCompetitorDTO(DashboardDispatchContext dashboardDispatchContext, TrackedRace trackedRace, int rank, Competitor competitor) { StartAnalysisCompetitorDTO startAnalysisCompetitorDTOsForRace = new StartAnalysisCompetitorDTO(); + Boat boatOfCompetitor = trackedRace.getBoatOfCompetitor(competitor); startAnalysisCompetitorDTOsForRace.competitorDTO = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore() - .convertToCompetitorDTO(competitor); + .convertToCompetitorDTO(competitor, boatOfCompetitor); startAnalysisCompetitorDTOsForRace.rankingTableEntryDTO = createRankTableEntry(trackedRace, rank, competitor); return startAnalysisCompetitorDTOsForRace; } diff --git a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/LeaderboardCompetitorsDTO.java b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/LeaderboardCompetitorsDTO.java index f402d3031eb..24470dfa69f 100644 --- a/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/LeaderboardCompetitorsDTO.java +++ b/java/com.sap.sailing.dashboards.gwt/src/main/java/com/sap/sailing/dashboards/gwt/shared/dto/LeaderboardCompetitorsDTO.java @@ -2,7 +2,7 @@ package com.sap.sailing.dashboards.gwt.shared.dto; import java.util.List; -import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sse.gwt.dispatch.shared.commands.Result; /** @@ -11,15 +11,15 @@ import com.sap.sse.gwt.dispatch.shared.commands.Result; */ public class LeaderboardCompetitorsDTO implements Result { - private List competitors; + private List competitors; public LeaderboardCompetitorsDTO() {} - public List getCompetitors() { + public List getCompetitors() { return competitors; } - public void setCompetitors(List competitors) { + public void setCompetitors(List competitors) { this.competitors = competitors; } } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java index 97132feb98b..1ab152cc2f4 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTO.java @@ -1,56 +1,15 @@ package com.sap.sailing.domain.common.dto; -import java.io.Serializable; - -import com.sap.sailing.domain.common.racelog.tracking.MappableToDevice; -import com.sap.sse.common.Color; -import com.sap.sse.common.Duration; - -public interface CompetitorDTO extends Serializable, MappableToDevice { - - String getTwoLetterIsoCountryCode(); - - String getThreeLetterIocCountryCode(); - - String getCountryName(); - - String getIdAsString(); - +public interface CompetitorDTO extends CompetitorWithoutBoatDTO { String getSailID(); - - String getSearchTag(); - - /** - * If the {@code searchTag} is not contained in {@link #getSearchTag()}, appends it to the search tag, separated by a space character - */ - void addToSearchTag(String searchTag); - BoatDTO getBoat(); - BoatClassDTO getBoatClass(); - - String getName(); - String getShortName(); - - Color getColor(); + BoatDTO getBoat(); - String getEmail(); - - boolean hasEmail(); - /** * A regular instance will simply return this object. A compacted version may compute the result by looking it up * from the previous version of the enclosing leaderboard. */ CompetitorDTO getCompetitorFromPrevious(LeaderboardDTO previousVersion); - - String getFlagImageURL(); - - String getImageURL(); - - Double getTimeOnTimeFactor(); - - Duration getTimeOnDistanceAllowancePerNauticalMile(); - } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java index b20ec943575..e332c25e0d4 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorDTOImpl.java @@ -5,52 +5,21 @@ import java.io.Serializable; import com.sap.sse.common.Color; import com.sap.sse.common.Duration; -/** - * Equality and hash code are based on the {@link #getIdAsString() ID}, the {@link #getSailID() sail number}, the - * {@link #getBoatClass() boat class} (whose equality and hash code, in turn, depends on its name) and the - * {@link #getThreeLetterIocCountryCode() IOC country code}. Note that the three latter properties are subject - * to change for a competitor while the ID remains unchanged. - * - * @author Axel Uhl (d043530) - * - */ -public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serializable { - private static final long serialVersionUID = -4997852354821083154L; - private String countryName; - private String twoLetterIsoCountryCode; - private String threeLetterIocCountryCode; - private Color color; - private String shortName; - private String email; - private String searchTag; - private String idAsString; +public class CompetitorDTOImpl extends CompetitorWithoutBoatDTOImpl implements CompetitorDTO, Serializable { + private static final long serialVersionUID = 6749455739529431935L; private BoatClassDTO boatClass; private BoatDTO boat; - private String imageURL; - private String flagImageURL; - private Double timeOnTimeFactor; - private Duration timeOnDistanceAllowancePerNauticalMile; public CompetitorDTOImpl() {} public CompetitorDTOImpl(String name, String shortName, Color color, String email, String twoLetterIsoCountryCode, String threeLetterIocCountryCode, String countryName, String idAsString, String imageURL, String flagImageURL, BoatDTO boat, BoatClassDTO boatClass, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) { - super(name); - this.shortName = shortName; - this.color = color; - this.email = email; - this.twoLetterIsoCountryCode = twoLetterIsoCountryCode; - this.threeLetterIocCountryCode = threeLetterIocCountryCode; - this.countryName = countryName; - this.idAsString = idAsString; - this.imageURL = imageURL; - this.flagImageURL = flagImageURL; + super(name, shortName, color, email, twoLetterIsoCountryCode, threeLetterIocCountryCode, + countryName, idAsString, imageURL, flagImageURL, + timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag); this.boat = boat; this.boatClass = boatClass; - this.timeOnTimeFactor = timeOnTimeFactor; - this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile; - this.searchTag = searchTag; } @Override @@ -59,16 +28,6 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial int result = super.hashCode(); result = prime * result + ((boatClass == null) ? 0 : boatClass.hashCode()); result = prime * result + ((boat == null) ? 0 : boat.hashCode()); - result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode()); - result = prime * result + ((color == null) ? 0 : color.hashCode()); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((shortName == null) ? 0 : shortName.hashCode()); - result = prime * result + ((threeLetterIocCountryCode == null) ? 0 : threeLetterIocCountryCode.hashCode()); - result = prime * result + ((imageURL == null) ? 0 : imageURL.hashCode()); - result = prime * result + ((flagImageURL == null) ? 0 : flagImageURL.hashCode()); - result = prime * result + ((timeOnTimeFactor == null) ? 0 : timeOnTimeFactor.hashCode()); - result = prime * result + ((timeOnDistanceAllowancePerNauticalMile == null) ? 0 : timeOnDistanceAllowancePerNauticalMile.hashCode()); - result = prime * result + ((searchTag == null) ? 0 : searchTag.hashCode()); return result; } @@ -91,146 +50,22 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial return false; } else if (!boat.equals(other.boat)) return false; - if (idAsString == null) { - if (other.idAsString != null) - return false; - } else if (!idAsString.equals(other.idAsString)) - return false; - if (threeLetterIocCountryCode == null) { - if (other.threeLetterIocCountryCode != null) - return false; - } else if (!threeLetterIocCountryCode.equals(other.threeLetterIocCountryCode)) - return false; - if (color == null) { - if (other.color != null) - return false; - } else if (!color.equals(other.color)) - return false; - if (email == null) { - if (other.email != null) - return false; - } else if (!email.equals(other.email)) - return false; - if (shortName == null) { - if (other.shortName != null) - return false; - } else if (!shortName.equals(other.shortName)) - return false; - if (imageURL == null) { - if (other.imageURL != null) - return false; - } else if (!imageURL.equals(other.imageURL)) - return false; - if (flagImageURL == null) { - if (other.flagImageURL != null) - return false; - } else if (!flagImageURL.equals(other.flagImageURL)) - return false; - if (timeOnTimeFactor == null) { - if (other.timeOnTimeFactor != null) - return false; - } else if (!timeOnTimeFactor.equals(other.timeOnTimeFactor)) - return false; - if (timeOnDistanceAllowancePerNauticalMile == null) { - if (other.timeOnDistanceAllowancePerNauticalMile != null) - return false; - } else if (!timeOnDistanceAllowancePerNauticalMile.equals(other.timeOnDistanceAllowancePerNauticalMile)) - return false; - if (searchTag == null) { - if (other.searchTag != null) - return false; - } else if (!searchTag.equals(other.searchTag)) - return false; return true; } - @Override - public String getTwoLetterIsoCountryCode() { - return twoLetterIsoCountryCode; - } - - @Override - public String getThreeLetterIocCountryCode() { - return threeLetterIocCountryCode; - } - - @Override - public String getCountryName() { - return countryName; - } - - @Override - public String getShortName() { - return shortName; - } - - @Override - public String getSailID() { - return boat==null?null:boat.getSailId(); - } - - @Override - public String getImageURL() { - return imageURL; - } - - @Override - public String getFlagImageURL() { - return flagImageURL; - } - - @Override - public String getIdAsString() { - return idAsString; - } - - @Override - public BoatClassDTO getBoatClass() { - return boatClass; - } - @Override public CompetitorDTO getCompetitorFromPrevious(LeaderboardDTO previousVersion) { return this; } @Override - public Color getColor() { - return color; - } - - @Override - public String getSearchTag() { - return searchTag; + public String getSailID() { + return boat==null?null:boat.getSailId(); } @Override - public void addToSearchTag(String searchTag) { - if (this.searchTag == null) { - this.searchTag = searchTag; - } else if (!this.searchTag.contains(searchTag)) { - this.searchTag += " "+searchTag; - } - } - - @Override - public String getEmail() { - return email; - } - - @Override - public boolean hasEmail() { - return email != null && !email.isEmpty(); - } - - @Override - public Double getTimeOnTimeFactor() { - return timeOnTimeFactor; - } - - @Override - public Duration getTimeOnDistanceAllowancePerNauticalMile() { - return timeOnDistanceAllowancePerNauticalMile; + public BoatClassDTO getBoatClass() { + return boatClass; } @Override diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorWithoutBoatDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorWithoutBoatDTO.java new file mode 100644 index 00000000000..68ace767363 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorWithoutBoatDTO.java @@ -0,0 +1,44 @@ +package com.sap.sailing.domain.common.dto; + +import java.io.Serializable; + +import com.sap.sailing.domain.common.racelog.tracking.MappableToDevice; +import com.sap.sse.common.Color; +import com.sap.sse.common.Duration; + +public interface CompetitorWithoutBoatDTO extends Serializable, MappableToDevice { + + String getTwoLetterIsoCountryCode(); + + String getThreeLetterIocCountryCode(); + + String getCountryName(); + + String getIdAsString(); + + String getSearchTag(); + + /** + * If the {@code searchTag} is not contained in {@link #getSearchTag()}, appends it to the search tag, separated by a space character + */ + void addToSearchTag(String searchTag); + + String getName(); + + String getShortName(); + + Color getColor(); + + String getEmail(); + + boolean hasEmail(); + + String getFlagImageURL(); + + String getImageURL(); + + Double getTimeOnTimeFactor(); + + Duration getTimeOnDistanceAllowancePerNauticalMile(); + +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorWithoutBoatDTOImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorWithoutBoatDTOImpl.java new file mode 100644 index 00000000000..229af7af490 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/CompetitorWithoutBoatDTOImpl.java @@ -0,0 +1,204 @@ +package com.sap.sailing.domain.common.dto; + +import java.io.Serializable; + +import com.sap.sse.common.Color; +import com.sap.sse.common.Duration; + +/** + * Equality and hash code are based on the {@link #getIdAsString() ID}, the {@link #getSailID() sail number}, the + * {@link #getBoatClass() boat class} (whose equality and hash code, in turn, depends on its name) and the + * {@link #getThreeLetterIocCountryCode() IOC country code}. Note that the three latter properties are subject + * to change for a competitor while the ID remains unchanged. + * + * @author Axel Uhl (d043530) + * + */ +public class CompetitorWithoutBoatDTOImpl extends NamedDTO implements CompetitorWithoutBoatDTO, Serializable { + private static final long serialVersionUID = -4997852354821083154L; + private String countryName; + private String twoLetterIsoCountryCode; + private String threeLetterIocCountryCode; + private Color color; + private String shortName; + private String email; + private String searchTag; + private String idAsString; + private String imageURL; + private String flagImageURL; + private Double timeOnTimeFactor; + private Duration timeOnDistanceAllowancePerNauticalMile; + + public CompetitorWithoutBoatDTOImpl() {} + + public CompetitorWithoutBoatDTOImpl(String name, String shortName, Color color, String email, String twoLetterIsoCountryCode, String threeLetterIocCountryCode, + String countryName, String idAsString, String imageURL, String flagImageURL, + Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) { + super(name); + this.shortName = shortName; + this.color = color; + this.email = email; + this.twoLetterIsoCountryCode = twoLetterIsoCountryCode; + this.threeLetterIocCountryCode = threeLetterIocCountryCode; + this.countryName = countryName; + this.idAsString = idAsString; + this.imageURL = imageURL; + this.flagImageURL = flagImageURL; + this.timeOnTimeFactor = timeOnTimeFactor; + this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile; + this.searchTag = searchTag; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode()); + result = prime * result + ((color == null) ? 0 : color.hashCode()); + result = prime * result + ((email == null) ? 0 : email.hashCode()); + result = prime * result + ((shortName == null) ? 0 : shortName.hashCode()); + result = prime * result + ((threeLetterIocCountryCode == null) ? 0 : threeLetterIocCountryCode.hashCode()); + result = prime * result + ((imageURL == null) ? 0 : imageURL.hashCode()); + result = prime * result + ((flagImageURL == null) ? 0 : flagImageURL.hashCode()); + result = prime * result + ((timeOnTimeFactor == null) ? 0 : timeOnTimeFactor.hashCode()); + result = prime * result + ((timeOnDistanceAllowancePerNauticalMile == null) ? 0 : timeOnDistanceAllowancePerNauticalMile.hashCode()); + result = prime * result + ((searchTag == null) ? 0 : searchTag.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + CompetitorWithoutBoatDTOImpl other = (CompetitorWithoutBoatDTOImpl) obj; + if (idAsString == null) { + if (other.idAsString != null) + return false; + } else if (!idAsString.equals(other.idAsString)) + return false; + if (threeLetterIocCountryCode == null) { + if (other.threeLetterIocCountryCode != null) + return false; + } else if (!threeLetterIocCountryCode.equals(other.threeLetterIocCountryCode)) + return false; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (email == null) { + if (other.email != null) + return false; + } else if (!email.equals(other.email)) + return false; + if (shortName == null) { + if (other.shortName != null) + return false; + } else if (!shortName.equals(other.shortName)) + return false; + if (imageURL == null) { + if (other.imageURL != null) + return false; + } else if (!imageURL.equals(other.imageURL)) + return false; + if (flagImageURL == null) { + if (other.flagImageURL != null) + return false; + } else if (!flagImageURL.equals(other.flagImageURL)) + return false; + if (timeOnTimeFactor == null) { + if (other.timeOnTimeFactor != null) + return false; + } else if (!timeOnTimeFactor.equals(other.timeOnTimeFactor)) + return false; + if (timeOnDistanceAllowancePerNauticalMile == null) { + if (other.timeOnDistanceAllowancePerNauticalMile != null) + return false; + } else if (!timeOnDistanceAllowancePerNauticalMile.equals(other.timeOnDistanceAllowancePerNauticalMile)) + return false; + if (searchTag == null) { + if (other.searchTag != null) + return false; + } else if (!searchTag.equals(other.searchTag)) + return false; + return true; + } + + @Override + public String getTwoLetterIsoCountryCode() { + return twoLetterIsoCountryCode; + } + + @Override + public String getThreeLetterIocCountryCode() { + return threeLetterIocCountryCode; + } + + @Override + public String getCountryName() { + return countryName; + } + + @Override + public String getShortName() { + return shortName; + } + + @Override + public String getImageURL() { + return imageURL; + } + + @Override + public String getFlagImageURL() { + return flagImageURL; + } + + @Override + public String getIdAsString() { + return idAsString; + } + + @Override + public Color getColor() { + return color; + } + + @Override + public String getSearchTag() { + return searchTag; + } + + @Override + public void addToSearchTag(String searchTag) { + if (this.searchTag == null) { + this.searchTag = searchTag; + } else if (!this.searchTag.contains(searchTag)) { + this.searchTag += " "+searchTag; + } + } + + @Override + public String getEmail() { + return email; + } + + @Override + public boolean hasEmail() { + return email != null && !email.isEmpty(); + } + + @Override + public Double getTimeOnTimeFactor() { + return timeOnTimeFactor; + } + + @Override + public Duration getTimeOnDistanceAllowancePerNauticalMile() { + return timeOnDistanceAllowancePerNauticalMile; + } +} diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java index 0dc91a3c062..8b7e340109e 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java @@ -89,10 +89,12 @@ import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformat import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.scoring.impl.RaceLogAdditionalScoringInformationEventImpl; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogDenoteForTrackingEventImpl; +import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogRegisterCompetitorAndBoatEventImpl; import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogRegisterCompetitorEventImpl; import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogStartTrackingEventImpl; import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogUseCompetitorsFromRaceLogEventImpl; @@ -102,6 +104,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEnde import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent; @@ -111,6 +114,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMa import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl; +import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorAndBoatEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRevokeEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEventImpl; @@ -213,7 +217,7 @@ import com.sap.sailing.domain.tracking.impl.WindTrackImpl; import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException; import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.BoatJsonDeserializer; -import com.sap.sailing.server.gateway.deserialization.impl.CompetitorWithBoatJsonDeserializer; +import com.sap.sailing.server.gateway.deserialization.impl.CompetitorJsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.DeviceConfigurationJsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.Helpers; import com.sap.sailing.server.gateway.deserialization.impl.RegattaConfigurationJsonDeserializer; @@ -240,7 +244,7 @@ import com.sap.sse.util.ThreadPoolUtil; public class DomainObjectFactoryImpl implements DomainObjectFactory { private static final Logger logger = Logger.getLogger(DomainObjectFactoryImpl.class.getName()); - private final CompetitorWithBoatJsonDeserializer competitorDeserializer; + private final CompetitorJsonDeserializer competitorDeserializer; private final BoatJsonDeserializer boatDeserializer; private final DB database; @@ -270,7 +274,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { this.raceTrackingConnectivityParamsServiceFinder = null; } this.baseDomainFactory = baseDomainFactory; - this.competitorDeserializer = CompetitorWithBoatJsonDeserializer.create(baseDomainFactory); + this.competitorDeserializer = CompetitorJsonDeserializer.create(baseDomainFactory); this.boatDeserializer = BoatJsonDeserializer.create(baseDomainFactory); this.database = db; } @@ -1413,6 +1417,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return loadRaceLogRevokeEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); } else if (eventClass.equals(RaceLogRegisterCompetitorEvent.class.getSimpleName())) { return loadRaceLogRegisterCompetitorEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); + } else if (eventClass.equals(RaceLogRegisterCompetitorAndBoatEvent.class.getSimpleName())) { + return loadRaceLogRegisterCompetitorAndBoatEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); } else if (eventClass.equals(RaceLogAdditionalScoringInformationEvent.class.getSimpleName())) { return loadRaceLogAdditionalScoringInformationEvent(createdAt, author, logicalTimePoint, id, passId, competitors, dbObject); } else if (eventClass.equals(RaceLogFixedMarkPassingEvent.class.getSimpleName())){ @@ -1469,6 +1475,15 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return new RaceLogRegisterCompetitorEventImpl(createdAt, logicalTimePoint, author, id, passId, comp); } + private RaceLogEvent loadRaceLogRegisterCompetitorAndBoatEvent(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, + Serializable id, Integer passId, List competitors, DBObject dbObject) { + Serializable competitorId = (Serializable) dbObject.get(FieldNames.RACE_LOG_COMPETITOR_ID.name()); + Serializable boatId = (Serializable) dbObject.get(FieldNames.RACE_LOG_BOAT_ID.name()); + Competitor comp = baseDomainFactory.getCompetitorStore().getExistingCompetitorById(competitorId); + Boat boat = baseDomainFactory.getCompetitorStore().getExistingBoatById(boatId); + return new RaceLogRegisterCompetitorAndBoatEventImpl(createdAt, logicalTimePoint, author, id, passId, comp, boat); + } + private RaceLogEvent loadRaceLogAdditionalScoringInformationEvent(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, Integer passId, List competitors, DBObject dbObject) { Object additionalScoringInformationTypeInfo = dbObject.get(FieldNames.RACE_LOG_ADDITIONAL_SCORING_INFORMATION_TYPE.name()); @@ -1705,6 +1720,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return loadRegattaLogCloseOpenEndedDeviceMappingEvent(createdAt, author, logicalTimePoint, id, dbObject); } else if (eventClass.equals(RegattaLogRegisterCompetitorEvent.class.getSimpleName())) { return loadRegattaLogRegisterCompetitorEvent(createdAt, author, logicalTimePoint, id, dbObject); + } else if (eventClass.equals(RegattaLogRegisterCompetitorAndBoatEvent.class.getSimpleName())) { + return loadRegattaLogRegisterCompetitorAndBoatEvent(createdAt, author, logicalTimePoint, id, dbObject); } else if (eventClass.equals(RegattaLogSetCompetitorTimeOnTimeFactorEvent.class.getSimpleName())) { return loadRegattaLogSetCompetitorTimeOnTimeFactorEvent(createdAt, author, logicalTimePoint, id, dbObject); } else if (eventClass.equals(RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent.class.getSimpleName())) { @@ -1723,6 +1740,12 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return comp; } + private Boat getBoatByID(DBObject dbObject) { + Serializable boatId = (Serializable) dbObject.get(FieldNames.REGATTA_LOG_BOAT_ID.name()); + Boat boat = baseDomainFactory.getCompetitorStore().getExistingBoatById(boatId); + return boat; + } + private RegattaLogEvent loadRegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, DBObject dbObject) { final Competitor comp = getCompetitorByID(dbObject); @@ -1770,6 +1793,27 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { return result; } + private RegattaLogRegisterCompetitorAndBoatEvent loadRegattaLogRegisterCompetitorAndBoatEvent(TimePoint createdAt, AbstractLogEventAuthor author, + TimePoint logicalTimePoint, Serializable id, DBObject dbObject) { + Competitor comp = getCompetitorByID(dbObject); + Boat boat = getBoatByID(dbObject); + final RegattaLogRegisterCompetitorAndBoatEvent result; + if (comp == null || boat == null) { + result = null; + if (comp == null) { + logger.log(Level.SEVERE, "Couldn't resolve competitor with ID "+dbObject.get(FieldNames.REGATTA_LOG_COMPETITOR_ID.name())+ + " from registration event with ID "+id+". Skipping this competitor registration."); + } + if (boat == null) { + logger.log(Level.SEVERE, "Couldn't resolve boat with ID "+dbObject.get(FieldNames.REGATTA_LOG_BOAT_ID.name())+ + " from registration event with ID "+id+". Skipping this competitor registration."); + } + } else { + result = new RegattaLogRegisterCompetitorAndBoatEventImpl(createdAt, logicalTimePoint, author, id, comp, boat); + } + return result; + } + private RegattaLogCloseOpenEndedDeviceMappingEvent loadRegattaLogCloseOpenEndedDeviceMappingEvent(TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id, DBObject dbObject) { Serializable deviceMappingEventId = Helpers.tryUuidConversion((Serializable) dbObject.get( diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java index 8e5536c4bc6..e19af70698d 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java @@ -100,7 +100,7 @@ public enum FieldNames { RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME, RACE_LOG_GOLF_DOWN_TIME, RACE_LOG_START_PROCEDURE_TYPE, RACE_LOG_PROTEST_START_TIME, RACE_LOG_PROTEST_END_TIME, RACE_LOG_COURSE_DESIGN_NAME, RACE_LOG_REVOKED_EVENT_ID, RACE_LOG_REVOKED_EVENT_TYPE, RACE_LOG_REVOKED_EVENT_SHORT_INFO, RACE_LOG_REVOKED_REASON, RACE_LOG_DEVICE_MAPPING_EVENT_ID, - RACE_LOG_CLOSING_TIMEPOINT, TIMEPOINT_OF_FIXED_MARKPASSING, INDEX_OF_PASSED_WAYPOINT,INDEX_OF_FIRST_SUPPRESSED_WAYPOINT, MARK, RACE_LOG_COMPETITOR_ID, + RACE_LOG_CLOSING_TIMEPOINT, TIMEPOINT_OF_FIXED_MARKPASSING, INDEX_OF_PASSED_WAYPOINT,INDEX_OF_FIRST_SUPPRESSED_WAYPOINT, MARK, RACE_LOG_COMPETITOR_ID, RACE_LOG_BOAT_ID, RACE_LOG_DEPDENDENT_ON_FLEET, RACE_LOG_DEPDENDENT_ON_RACECOLUMN, RACE_LOG_DEPDENDENT_ON_REGATTALIKE, RACE_LOG_START_TIME_DIFFERENCE_IN_MS, RACE_LOG_FINISHING_TIME_AS_MILLIS, /** @deprecated Replaced by {@link #REGATTA_LOG_FROM}; auto-migration from race log device mappings to regatta log is implemented */ @Deprecated RACE_LOG_FROM, @@ -116,7 +116,7 @@ public enum FieldNames { // did not reuse RACE_LOG* types, as this would require handling old versions of all events REGATTA_LOG_IDENTIFIER_TYPE, REGATTA_LOG_IDENTIFIER_NAME, REGATTA_LOG_EVENT_ID, REGATTA_LOG_EVENT_CREATED_AT, REGATTA_LOG_EVENT_AUTHOR_NAME, REGATTA_LOG_EVENT_AUTHOR_PRIORITY, REGATTA_LOG_EVENT_CLASS, REGATTA_LOG_REVOKED_EVENT_ID, REGATTA_LOG_REVOKED_EVENT_TYPE, REGATTA_LOG_REVOKED_EVENT_SHORT_INFO, - REGATTA_LOG_REVOKED_REASON, REGATTA_LOG_COMPETITOR_ID, REGATTA_LOG_DEVICE_MAPPING_EVENT_ID, REGATTA_LOG_CLOSING_TIMEPOINT, + REGATTA_LOG_REVOKED_REASON, REGATTA_LOG_COMPETITOR_ID, REGATTA_LOG_BOAT_ID, REGATTA_LOG_DEVICE_MAPPING_EVENT_ID, REGATTA_LOG_CLOSING_TIMEPOINT, REGATTA_LOG_FROM, REGATTA_LOG_TO, REGATTA_LOG_EVENT, REGATTA_LOG_MARK, // remote server reference fields diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java index d99e81f4c78..e4daed19086 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java @@ -46,6 +46,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEven import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -56,6 +57,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompeti import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent; @@ -114,7 +116,6 @@ import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.server.gateway.serialization.JsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.BoatJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerializer; -import com.sap.sailing.server.gateway.serialization.impl.CompetitorWithBoatJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.DeviceConfigurationJsonSerializer; import com.sap.sailing.server.gateway.serialization.impl.RegattaConfigurationJsonSerializer; import com.sap.sse.common.Duration; @@ -132,7 +133,7 @@ import com.sap.sse.shared.media.VideoDescriptor; public class MongoObjectFactoryImpl implements MongoObjectFactory { private static Logger logger = Logger.getLogger(MongoObjectFactoryImpl.class.getName()); private final DB database; - private final CompetitorWithBoatJsonSerializer competitorSerializer = CompetitorWithBoatJsonSerializer.create(); + private final CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create(); private final BoatJsonSerializer boatSerializer = BoatJsonSerializer.create(); private final TypeBasedServiceFinder deviceIdentifierServiceFinder; private final TypeBasedServiceFinder raceTrackingConnectivityParamsServiceFinder; @@ -879,7 +880,14 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogRegisterCompetitorEvent(event)); return result; } - + + public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogRegisterCompetitorAndBoatEvent event) { + BasicDBObject result = new BasicDBObject(); + storeRaceLogIdentifier(raceLogIdentifier, result); + result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogRegisterCompetitorAndBoatEvent(event)); + return result; + } + public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogEndOfTrackingEvent event) { BasicDBObject result = new BasicDBObject(); storeRaceLogIdentifier(raceLogIdentifier, result); @@ -1021,6 +1029,15 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { return result; } + private Object storeRaceLogRegisterCompetitorAndBoatEvent(RaceLogRegisterCompetitorAndBoatEvent event) { + DBObject result = new BasicDBObject(); + storeRaceLogEventProperties(event, result); + result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogRegisterCompetitorAndBoatEvent.class.getSimpleName()); + result.put(FieldNames.RACE_LOG_COMPETITOR_ID.name(), event.getCompetitor().getId()); + result.put(FieldNames.RACE_LOG_BOAT_ID.name(), event.getBoat().getId()); + return result; + } + public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogUseCompetitorsFromRaceLogEvent event) { BasicDBObject result = new BasicDBObject(); storeRaceLogIdentifier(raceLogIdentifier, result); @@ -1471,6 +1488,14 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { storeRegattaLogEvent(regattaLikeId, result); } + public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogRegisterCompetitorAndBoatEvent event) { + DBObject result = createBasicRegattaLogEventDBObject(event); + result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogRegisterCompetitorAndBoatEvent.class.getSimpleName()); + result.put(FieldNames.REGATTA_LOG_COMPETITOR_ID.name(), event.getCompetitor().getId()); + result.put(FieldNames.REGATTA_LOG_BOAT_ID.name(), event.getBoat().getId()); + storeRegattaLogEvent(regattaLikeId, result); + } + public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogCloseOpenEndedDeviceMappingEvent event) { DBObject result = createBasicRegattaLogEventDBObject(event); result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogCloseOpenEndedDeviceMappingEvent.class.getSimpleName()); diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java index a65b20e14ad..f5aa8f03605 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogStoreVisitor.java @@ -25,6 +25,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEven import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -146,6 +147,12 @@ public class MongoRaceLogStoreVisitor implements RaceLogEventVisitor { mongoObjectFactory.storeRaceLogEventEvent(object); } + @Override + public void visit(RaceLogRegisterCompetitorAndBoatEvent event) { + DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); + mongoObjectFactory.storeRaceLogEventEvent(object); + } + @Override public void visit(RaceLogAdditionalScoringInformationEvent event) { DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event); diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRegattaLogStoreVisitor.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRegattaLogStoreVisitor.java index 09398ffcbaa..2dd3aa01f86 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRegattaLogStoreVisitor.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRegattaLogStoreVisitor.java @@ -8,6 +8,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEve import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent; @@ -57,6 +58,11 @@ public class MongoRegattaLogStoreVisitor implements RegattaLogEventVisitor { mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event); } + @Override + public void visit(RegattaLogRegisterCompetitorAndBoatEvent event) { + mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event); + } + @Override public void visit(RegattaLogSetCompetitorTimeOnTimeFactorEvent event) { mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event); diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java index 2669506e62f..6dc3530251f 100755 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java @@ -146,11 +146,11 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter { boatClass = rLeaderboard.getRegatta().getBoatClass(); } else { if (!Util.isEmpty(raceColumn.getAllCompetitors(fleet))) { - boatClass = findDominatingBoatClass(raceColumn.getAllCompetitors(fleet)); + boatClass = findDominatingBoatClass(raceColumn.getAllCompetitorsAndTheirBoats(fleet).values()); } else if (!Util.isEmpty(raceColumn.getAllCompetitors())) { - boatClass = findDominatingBoatClass(raceColumn.getAllCompetitors()); + boatClass = findDominatingBoatClass(raceColumn.getAllCompetitorsAndTheirBoats().values()); } else if (!Util.isEmpty(leaderboard.getAllCompetitors())) { - boatClass = findDominatingBoatClass(leaderboard.getAllCompetitors()); + boatClass = leaderboard.getBoatClass(); } else { throw new NotDenotableForRaceLogTrackingException("Couldn't infer boat class, no competitors on race and leaderboard"); } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java index fb4f8d3d823..8bc1dcfdafa 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/RaceLogEventVisitor.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.abstractlog.race; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -42,6 +43,8 @@ public interface RaceLogEventVisitor { public void visit(RaceLogRegisterCompetitorEvent event); + public void visit(RaceLogRegisterCompetitorAndBoatEvent event); + public void visit(RaceLogAdditionalScoringInformationEvent additionalScoringInformation); public void visit(RaceLogFixedMarkPassingEvent event); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java index 8407d6f2d86..9f036e7adfa 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/AbstractRaceLogChangedVisitor.java @@ -23,6 +23,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEven import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -108,7 +109,12 @@ public abstract class AbstractRaceLogChangedVisitor implements RaceLogEventVisit public void visit(RaceLogRegisterCompetitorEvent event) { notifyListenerAboutEventAdded(event); } - + + @Override + public void visit(RaceLogRegisterCompetitorAndBoatEvent event) { + notifyListenerAboutEventAdded(event); + } + @Override public void visit(RaceLogAdditionalScoringInformationEvent additionalScoringInformation) { notifyListenerAboutEventAdded(additionalScoringInformation); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java index bff059adf00..c6fdaaa1c9c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/impl/BaseRaceLogEventVisitor.java @@ -22,6 +22,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEven import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -115,7 +116,12 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor { public void visit(RaceLogRegisterCompetitorEvent event) { } - + + @Override + public void visit(RaceLogRegisterCompetitorAndBoatEvent event) { + + } + @Override public void visit(RaceLogAdditionalScoringInformationEvent event) { diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/RaceLogRegisterCompetitorAndBoatEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/RaceLogRegisterCompetitorAndBoatEvent.java new file mode 100644 index 00000000000..4c48ba84796 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/RaceLogRegisterCompetitorAndBoatEvent.java @@ -0,0 +1,10 @@ +package com.sap.sailing.domain.abstractlog.race.tracking; + +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; +import com.sap.sailing.domain.abstractlog.shared.events.RegisterCompetitorAndBoatEvent; + +public interface RaceLogRegisterCompetitorAndBoatEvent + extends RaceLogEvent, RegisterCompetitorAndBoatEvent { + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/analyzing/impl/RegisteredCompetitorsAndBoatsAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/analyzing/impl/RegisteredCompetitorsAndBoatsAnalyzer.java new file mode 100644 index 00000000000..a05c26e9e81 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/analyzing/impl/RegisteredCompetitorsAndBoatsAnalyzer.java @@ -0,0 +1,44 @@ +package com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl; + +import java.util.Map; + +import com.sap.sailing.domain.abstractlog.race.RaceLog; +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogAnalyzer; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; +import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorsAndBoatsInLogAnalyzer; +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.Competitor; + +/** + * Used to find competitors (including their boats) of a race based on {@link RaceLog} and {@link RegattaLog} contents. Checks whether the + * competitors for the given race are registered on the RaceLog via {@link RaceLogUsesOwnCompetitorsAnalyzer} or on the + * RegattaLog and fetches the competitors appropriately. + * + * Should not be used by clients directly. Instead, get the competitor set from the {@code RaceColumn}, using either one + * of {@code getAllCompetitorsAndTheirBoats()} and {@code getAllCompetitorsAndTheirBoats(Fleet)}. Those methods automatically check whether a + * tracked race is present, which takes precedence over the Race/RegattaLog. + * + * @author Jan Bross (D056848) + * + */ +public class RegisteredCompetitorsAndBoatsAnalyzer extends RaceLogAnalyzer> { + private RegattaLog regattaLog; + + public RegisteredCompetitorsAndBoatsAnalyzer(RaceLog raceLog, RegattaLog regattaLog) { + super(raceLog); + this.regattaLog = regattaLog; + } + + @Override + protected Map performAnalysis() { + final Map result; + if (new RaceLogUsesOwnCompetitorsAnalyzer(getLog()).analyze()) { + // get Events from RaceLog + result = new CompetitorsAndBoatsInLogAnalyzer<>(getLog()).analyze(); + } else { + // get Events from RegattaLog + result = new CompetitorsAndBoatsInLogAnalyzer<>(regattaLog).analyze(); + } + return result; + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorAndBoatEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorAndBoatEventImpl.java new file mode 100644 index 00000000000..50daed3a0cd --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/tracking/impl/RaceLogRegisterCompetitorAndBoatEventImpl.java @@ -0,0 +1,62 @@ +package com.sap.sailing.domain.abstractlog.race.tracking.impl; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventData; +import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor; +import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEventDataImpl; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; +import com.sap.sailing.domain.abstractlog.shared.events.impl.BaseRegisterCompetitorAndBoatEventImpl; +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sse.common.TimePoint; + +public class RaceLogRegisterCompetitorAndBoatEventImpl extends BaseRegisterCompetitorAndBoatEventImpl implements + RaceLogRegisterCompetitorAndBoatEvent { + private static final long serialVersionUID = 1395401990335109923L; + private final RaceLogEventData raceLogEventData; + + /** + * @throws IllegalArgumentException + * if {@code competitor} is null + */ + public RaceLogRegisterCompetitorAndBoatEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Serializable id, int passId, Competitor competitor, Boat boat) + throws IllegalArgumentException { + super(createdAt, logicalTimePoint, author, id, competitor, boat); + this.raceLogEventData = new RaceLogEventDataImpl(null, passId); + } + + /** + * @throws IllegalArgumentException + * if {@code competitor} is null + */ + public RaceLogRegisterCompetitorAndBoatEventImpl(TimePoint logicalTimePoint, + AbstractLogEventAuthor author, int passId, Competitor competitor, Boat boat) + throws IllegalArgumentException { + this(now(), logicalTimePoint, author, randId(), passId, competitor, boat); + } + + @Override + public int getPassId() { + return raceLogEventData.getPassId(); + } + + @Override + public List getInvolvedBoats() { + return Collections.singletonList(getCompetitor()); + } + + @Override + public String toString() { + return raceLogEventData.toString(); + } + + @Override + public void accept(RaceLogEventVisitor visitor) { + visitor.visit(this); + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/RegattaLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/RegattaLogEventVisitor.java index 19780a1174b..feb61797389 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/RegattaLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/RegattaLogEventVisitor.java @@ -5,6 +5,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEve import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent; @@ -22,7 +23,9 @@ public interface RegattaLogEventVisitor { void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event); void visit(RegattaLogRegisterCompetitorEvent event); - + + void visit(RegattaLogRegisterCompetitorAndBoatEvent event); + void visit(RegattaLogSetCompetitorTimeOnTimeFactorEvent event); void visit(RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent event); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/RegattaLogRegisterCompetitorAndBoatEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/RegattaLogRegisterCompetitorAndBoatEvent.java new file mode 100644 index 00000000000..9c39e217079 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/RegattaLogRegisterCompetitorAndBoatEvent.java @@ -0,0 +1,10 @@ +package com.sap.sailing.domain.abstractlog.regatta.events; + +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor; +import com.sap.sailing.domain.abstractlog.shared.events.RegisterCompetitorAndBoatEvent; + +public interface RegattaLogRegisterCompetitorAndBoatEvent + extends RegattaLogEvent, RegisterCompetitorAndBoatEvent { + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/impl/RegattaLogRegisterCompetitorAndBoatEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/impl/RegattaLogRegisterCompetitorAndBoatEventImpl.java new file mode 100644 index 00000000000..b264687eb85 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/events/impl/RegattaLogRegisterCompetitorAndBoatEventImpl.java @@ -0,0 +1,39 @@ +package com.sap.sailing.domain.abstractlog.regatta.events.impl; + +import java.io.Serializable; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; +import com.sap.sailing.domain.abstractlog.shared.events.impl.BaseRegisterCompetitorAndBoatEventImpl; +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sse.common.TimePoint; + +public class RegattaLogRegisterCompetitorAndBoatEventImpl extends BaseRegisterCompetitorAndBoatEventImpl + implements RegattaLogRegisterCompetitorAndBoatEvent { + private static final long serialVersionUID = 3577775910921730978L; + + /** + * @throws IllegalArgumentException + * if {@code competitor} is null + */ + public RegattaLogRegisterCompetitorAndBoatEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Serializable id, Competitor competitor, Boat boat) throws IllegalArgumentException { + super(createdAt, logicalTimePoint, author, id, competitor, boat); + } + + /** + * @throws IllegalArgumentException + * if {@code competitor} is null + */ + public RegattaLogRegisterCompetitorAndBoatEventImpl(TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Competitor competitor, Boat boat) throws IllegalArgumentException { + super(logicalTimePoint, author, competitor, boat); + } + + @Override + public void accept(RegattaLogEventVisitor visitor) { + visitor.visit(this); + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/BaseRegattaLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/BaseRegattaLogEventVisitor.java index 808a9b9af97..df2c6e92249 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/BaseRegattaLogEventVisitor.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/BaseRegattaLogEventVisitor.java @@ -6,6 +6,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEve import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent; @@ -37,6 +38,10 @@ public class BaseRegattaLogEventVisitor implements RegattaLogEventVisitor { public void visit(RegattaLogRegisterCompetitorEvent event) { } + @Override + public void visit(RegattaLogRegisterCompetitorAndBoatEvent event) { + } + @Override public void visit(RegattaLogSetCompetitorTimeOnTimeFactorEvent event) { } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/RegattaLogEventListener.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/RegattaLogEventListener.java index bf9d9fd1cb2..dbe0f594062 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/RegattaLogEventListener.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/regatta/impl/RegattaLogEventListener.java @@ -7,6 +7,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEve import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent; +import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent; import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent; @@ -40,6 +41,11 @@ public abstract class RegattaLogEventListener implements RegattaLogEventVisitor eventAdded(event); } + @Override + public void visit(RegattaLogRegisterCompetitorAndBoatEvent event) { + eventAdded(event); + } + @Override public void visit(RegattaLogSetCompetitorTimeOnTimeFactorEvent event) { eventAdded(event); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorsAndBoatsInLogAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorsAndBoatsInLogAnalyzer.java new file mode 100644 index 00000000000..409dbc641aa --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorsAndBoatsInLogAnalyzer.java @@ -0,0 +1,50 @@ +package com.sap.sailing.domain.abstractlog.shared.analyzing; + +import java.util.HashMap; +import java.util.Map; + +import com.sap.sailing.domain.abstractlog.AbstractLog; +import com.sap.sailing.domain.abstractlog.AbstractLogEvent; +import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer; +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogRegisteredCompetitorsAnalyzer; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RegisteredCompetitorsAnalyzer; +import com.sap.sailing.domain.abstractlog.shared.events.RegisterCompetitorAndBoatEvent; +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.Competitor; + +/** + * This class searches for RegisterCompetitorEvents in the given log. + * + * TLDR: It's likely, that you shouldn't use this, but you might want to use {@link RegisteredCompetitorsAnalyzer} or {@link RaceLogRegisteredCompetitorsAnalyzer} + * + * Note that solemnly analyzing a certain race or RegattaLog my not lead the correct registered competitors for the race + * corresponding to the RaceLog/the races corresponding to the RegattaLog. + * + * This is the case as by default the competitors registered on the RegattaLog are used for each race of the regatta + * ignoring the ones in the RaceLog (if present). The RaceLog may override this behavior with the + * {@link RaceLogUseCompetitorsFromRaceLogEvent}. Is an event of this type present, the competitors written into the + * RaceLog are used instead of the competitors in the RegattaLog. + * + */ +public class CompetitorsAndBoatsInLogAnalyzer, EventT extends AbstractLogEvent, VisitorT> + extends BaseLogAnalyzer> { + + public CompetitorsAndBoatsInLogAnalyzer(LogT log) { + super(log); + } + + @Override + protected Map performAnalysis() { + Map result = new HashMap<>(); + + for (EventT event : getLog().getUnrevokedEvents()) { + if (event instanceof RegisterCompetitorAndBoatEvent) { + RegisterCompetitorAndBoatEvent competitorAndBoatEvent = (RegisterCompetitorAndBoatEvent) event; + result.put(competitorAndBoatEvent.getCompetitor(), competitorAndBoatEvent.getBoat()); + } + } + + return result; + } +} \ No newline at end of file diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/events/RegisterCompetitorAndBoatEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/events/RegisterCompetitorAndBoatEvent.java new file mode 100644 index 00000000000..2b5298f7a19 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/events/RegisterCompetitorAndBoatEvent.java @@ -0,0 +1,24 @@ +package com.sap.sailing.domain.abstractlog.shared.events; + +import com.sap.sailing.domain.abstractlog.AbstractLogEvent; +import com.sap.sailing.domain.abstractlog.Revokable; +import com.sap.sailing.domain.abstractlog.race.RaceLog; +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sse.common.IsManagedByCache; + +/** + * Register a competitor and the boat for that race using the {@link RaceLog} in racelog-tracked races. + * + * A dummy {@link Competitor} implementation with only an {@link Competitor#getId() id} may be used, + * if the competitor is known to already exist on the server, as it is + * {@link IsManagedByCache#resolve(com.sap.sailing.domain.base.SharedDomainFactory) resolved} + * on arrival. + * @author Frank Mittag + * + */ +public interface RegisterCompetitorAndBoatEvent extends AbstractLogEvent, Revokable { + Competitor getCompetitor(); + + Boat getBoat(); +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/events/impl/BaseRegisterCompetitorAndBoatEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/events/impl/BaseRegisterCompetitorAndBoatEventImpl.java new file mode 100644 index 00000000000..4803a13a1bf --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/events/impl/BaseRegisterCompetitorAndBoatEventImpl.java @@ -0,0 +1,59 @@ +package com.sap.sailing.domain.abstractlog.shared.events.impl; + +import java.io.Serializable; + +import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; +import com.sap.sailing.domain.abstractlog.impl.AbstractLogEventImpl; +import com.sap.sailing.domain.abstractlog.shared.events.RegisterCompetitorAndBoatEvent; +import com.sap.sailing.domain.base.Boat; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sse.common.TimePoint; + +public abstract class BaseRegisterCompetitorAndBoatEventImpl extends AbstractLogEventImpl implements + RegisterCompetitorAndBoatEvent { + private static final long serialVersionUID = 7528972504689931986L; + private final Competitor competitor; + private final Boat boat; + + /** + * @throws IllegalArgumentException + * if {@code competitor} is null + */ + public BaseRegisterCompetitorAndBoatEventImpl(TimePoint createdAt, TimePoint logicalTimePoint, + AbstractLogEventAuthor author, Serializable pId, Competitor competitor, Boat boat) throws IllegalArgumentException { + super(createdAt, logicalTimePoint, author, pId); + checkCompetitor(competitor); + this.competitor = competitor; + this.boat = boat; + } + + /** + * @throws IllegalArgumentException + * if {@code competitor} is null + */ + public BaseRegisterCompetitorAndBoatEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author, + Competitor competitor, Boat boat) throws IllegalArgumentException { + this(now(), logicalTimePoint, author, randId(), competitor, boat); + } + + private static void checkCompetitor(Competitor competitor) throws IllegalArgumentException { + if (competitor == null) { + throw new IllegalArgumentException("Competitor may not be null"); + } + } + + @Override + public Competitor getCompetitor() { + return competitor; + } + + @Override + public Boat getBoat() { + return boat; + } + + @Override + public String getShortInfo() { + return "competitor: " + getCompetitor().toString() + " with boat " + getBoat().toString(); + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorStore.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorStore.java index 8f6f8265e52..53a038bb847 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorStore.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/CompetitorStore.java @@ -7,6 +7,7 @@ import com.sap.sailing.domain.base.impl.DynamicBoat; import com.sap.sailing.domain.base.impl.DynamicTeam; import com.sap.sailing.domain.common.dto.BoatDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sse.common.Color; import com.sap.sse.common.Duration; @@ -75,8 +76,12 @@ public interface CompetitorStore extends CompetitorFactory, BoatFactory { void addCompetitors(Iterable competitors); - CompetitorDTO convertToCompetitorDTO(Competitor c); - + CompetitorWithoutBoatDTO convertToCompetitorWithoutBoatDTO(Competitor c); + + CompetitorDTO convertToCompetitorDTO(CompetitorWithBoat c); + + CompetitorDTO convertToCompetitorDTO(Competitor c, Boat b); + /** * Listeners added here are notified whenever {@link #updateCompetitor(String, String, Color, String, Nationality)} is called * for any competitor in this store. diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorWithoutBoatImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorWithoutBoatImpl.java new file mode 100644 index 00000000000..31da5747bda --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/CompetitorWithoutBoatImpl.java @@ -0,0 +1,226 @@ +package com.sap.sailing.domain.base.impl; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorChangeListener; +import com.sap.sailing.domain.base.SharedDomainFactory; +import com.sap.sse.common.Color; +import com.sap.sse.common.Duration; +import com.sap.sse.common.Util; + +public class CompetitorWithoutBoatImpl implements DynamicCompetitor { + private static final long serialVersionUID = 294603681016643157L; + private final DynamicTeam team; + private final Serializable id; + private String name; + private String shortName; + private String searchTag; + private Color color; + private transient Set listeners; + private String email; + private URI flagImage; + private Double timeOnTimeFactor; + private Duration timeOnDistanceAllowancePerNauticalMile; + + public CompetitorWithoutBoatImpl(Serializable id, String name, String shortName, Color color, String email, URI flagImage, DynamicTeam team, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) { + this.id = id; + this.name = name; + this.shortName = shortName; + this.team = team; + this.color = color; + this.email = email; + this.flagImage = flagImage; + this.timeOnTimeFactor = timeOnTimeFactor; + this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile; + this.searchTag = searchTag; + this.listeners = new HashSet(); + } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + listeners = new HashSet(); + } + + @Override + public String getName() { + return name; + } + + @Override + public String getShortName() { + return shortName; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public void setName(String newName) { + final String oldName = this.name; + if (!Util.equalsWithNull(oldName, newName)) { + this.name = newName; + for (CompetitorChangeListener listener : getListeners()) { + listener.nameChanged(oldName, newName); + } + } + } + + @Override + public void setShortName(String newShortName) { + final String oldShortName = this.shortName; + if (!Util.equalsWithNull(oldShortName, newShortName)) { + this.shortName = newShortName; + for (CompetitorChangeListener listener : getListeners()) { + listener.shortNameChanged(oldShortName, newShortName); + } + } + } + + + @Override + public Serializable getId() { + return id; + } + + @Override + public DynamicTeam getTeam() { + return team; + } + + @Override + public Competitor resolve(SharedDomainFactory domainFactory) { + Competitor result = domainFactory + .getOrCreateCompetitor(getId(), getName(), getShortName(), getColor(), getEmail(), getFlagImage(), getTeam(), + getTimeOnTimeFactor(), getTimeOnDistanceAllowancePerNauticalMile(), searchTag); + return result; + } + + @Override + public Color getColor() { + return color; + } + + public void setColor(Color color) { + final Color oldColor = this.color; + if (!Util.equalsWithNull(oldColor, color)) { + this.color = color; + for (CompetitorChangeListener listener : getListeners()) { + listener.colorChanged(oldColor, color); + } + } + } + + @Override + public void addCompetitorChangeListener(CompetitorChangeListener listener) { + synchronized (listeners) { + listeners.add(listener); + } + getTeam().addNationalityChangeListener(listener); + } + + @Override + public void removeCompetitorChangeListener(CompetitorChangeListener listener) { + synchronized (listeners) { + listeners.remove(listener); + } + getTeam().removeNationalityChangeListener(listener); + } + + private Iterable getListeners() { + synchronized (listeners) { + return new HashSet(listeners); + } + } + + @Override + public String getSearchTag() { + return searchTag; + } + + public void setSearchTag(String newSearchTag) { + final String oldSearchTag = this.searchTag; + if (!Util.equalsWithNull(oldSearchTag, newSearchTag)) { + this.searchTag = newSearchTag; + for (CompetitorChangeListener listener : getListeners()) { + listener.searchTagChanged(oldSearchTag, newSearchTag); + } + } + } + + @Override + public String getEmail() { + return email; + } + + public void setEmail(String newEmail) { + final String oldEmail = this.email; + if (!Util.equalsWithNull(oldEmail, newEmail)) { + this.email = newEmail; + for (CompetitorChangeListener listener : getListeners()) { + listener.emailChanged(oldEmail, newEmail); + } + } + } + + @Override + public boolean hasEmail(){ + return email != null && !email.isEmpty(); + } + + @Override + public URI getFlagImage() { + return flagImage; + } + + @Override + public void setFlagImage(URI flagImage) { + final URI oldFlagImage = this.flagImage; + this.flagImage = flagImage; + if (!Util.equalsWithNull(oldFlagImage, flagImage)) { + for (CompetitorChangeListener listener : getListeners()) { + listener.flagImageChanged(oldFlagImage, flagImage); + } + } + } + + @Override + public Double getTimeOnTimeFactor() { + return timeOnTimeFactor; + } + + @Override + public Duration getTimeOnDistanceAllowancePerNauticalMile() { + return timeOnDistanceAllowancePerNauticalMile; + } + + @Override + public void setTimeOnTimeFactor(Double timeOnTimeFactor) { + Double oldTimeOnTimeFactor = this.timeOnTimeFactor; + this.timeOnTimeFactor = timeOnTimeFactor; + if (!Util.equalsWithNull(oldTimeOnTimeFactor, timeOnTimeFactor)) { + for (CompetitorChangeListener listener : getListeners()) { + listener.timeOnTimeFactorChanged(oldTimeOnTimeFactor, timeOnTimeFactor); + } + } + } + + @Override + public void setTimeOnDistanceAllowancePerNauticalMile(Duration timeOnDistanceAllowancePerNauticalMile) { + Duration oldTimeOnDistanceAllowancePerNauticalMile = this.timeOnDistanceAllowancePerNauticalMile; + this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile; + if (!Util.equalsWithNull(oldTimeOnDistanceAllowancePerNauticalMile, timeOnDistanceAllowancePerNauticalMile)) { + for (CompetitorChangeListener listener : getListeners()) { + listener.timeOnDistanceAllowancePerNauticalMileChanged(oldTimeOnDistanceAllowancePerNauticalMile, timeOnDistanceAllowancePerNauticalMile); + } + } + } + +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java index e0f36db1099..023aeaa0764 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/TransientCompetitorStoreImpl.java @@ -18,12 +18,15 @@ import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.CompetitorStore; +import com.sap.sailing.domain.base.CompetitorWithBoat; import com.sap.sailing.domain.base.LeaderboardGroupBase; import com.sap.sailing.domain.base.Nationality; import com.sap.sailing.domain.common.dto.BoatClassDTO; import com.sap.sailing.domain.common.dto.BoatDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.CompetitorDTOImpl; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTOImpl; import com.sap.sse.common.Color; import com.sap.sse.common.CountryCode; import com.sap.sse.common.Duration; @@ -47,7 +50,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab */ private final Set competitorsToUpdateDuringGetOrCreate; - private transient WeakHashMap weakCompetitorDTOCache; + private transient WeakHashMap weakCompetitorDTOCache; private final Set boatsToUpdateDuringGetOrCreate; @@ -60,7 +63,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab competitorCache = new HashMap(); competitorsByIdAsString = new HashMap(); competitorsToUpdateDuringGetOrCreate = new HashSet(); - weakCompetitorDTOCache = new WeakHashMap(); + weakCompetitorDTOCache = new WeakHashMap(); competitorUpdateListeners = Collections.synchronizedSet(new HashSet()); boatCache = new HashMap(); boatsByIdAsString = new HashMap(); @@ -71,7 +74,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); - weakCompetitorDTOCache = new WeakHashMap(); + weakCompetitorDTOCache = new WeakHashMap(); competitorUpdateListeners = Collections.synchronizedSet(new HashSet()); weakBoatDTOCache = new WeakHashMap(); boatUpdateListeners = Collections.synchronizedSet(new HashSet()); @@ -246,11 +249,11 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab } @Override - public CompetitorDTO convertToCompetitorDTO(Competitor c) { + public CompetitorWithoutBoatDTO convertToCompetitorWithoutBoatDTO(Competitor c) { LockUtil.lockForRead(lock); boolean needToUnlockReadLock = true; try { - CompetitorDTO competitorDTO = weakCompetitorDTOCache.get(c); + CompetitorWithoutBoatDTO competitorDTO = weakCompetitorDTOCache.get(c); if (competitorDTO == null) { LockUtil.unlockAfterRead(lock); needToUnlockReadLock = false; @@ -259,18 +262,12 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab if (competitorDTO == null) { final Nationality nationality = c.getTeam().getNationality(); CountryCode countryCode = nationality == null ? null : nationality.getCountryCode(); - Boat b = c.getBoat(); - BoatClassDTO boatClassDTO = new BoatClassDTO(b.getBoatClass().getName(), b.getBoatClass().getDisplayName(), - b.getBoatClass().getHullLength(), b.getBoatClass().getHullBeam()); - BoatDTO boatDTO = new BoatDTO(b.getId().toString(), b.getName(), boatClassDTO, b.getSailID(), b.getColor()); - competitorDTO = new CompetitorDTOImpl(c.getName(), c.getShortName(), c.getColor(), c.getEmail(), countryCode == null ? "" + competitorDTO = new CompetitorWithoutBoatDTOImpl(c.getName(), c.getShortName(), c.getColor(), c.getEmail(), countryCode == null ? "" : countryCode.getTwoLetterISOCode(), countryCode == null ? "" : countryCode.getThreeLetterIOCCode(), countryCode == null ? "" : countryCode.getName(), c.getId().toString(), c.getTeam().getImage() == null ? null : c.getTeam().getImage().toString(), c.getFlagImage() == null ? null : c.getFlagImage().toString(), - boatDTO, - boatClassDTO, c.getTimeOnTimeFactor(), c.getTimeOnDistanceAllowancePerNauticalMile(), c.getSearchTag()); weakCompetitorDTOCache.put(c, competitorDTO); } @@ -285,6 +282,29 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab } } + @Override + public CompetitorDTO convertToCompetitorDTO(CompetitorWithBoat competitorWithBoat) { + return convertToCompetitorDTO(competitorWithBoat, competitorWithBoat.getBoat()); + } + @Override + public CompetitorDTO convertToCompetitorDTO(Competitor competitor, Boat b) { + CompetitorWithoutBoatDTO c = convertToCompetitorWithoutBoatDTO(competitor); + BoatClassDTO boatClassDTO = new BoatClassDTO(b.getBoatClass().getName(), b.getBoatClass().getDisplayName(), + b.getBoatClass().getHullLength(), b.getBoatClass().getHullBeam()); + BoatDTO boatDTO = new BoatDTO(b.getId().toString(), b.getName(), boatClassDTO, b.getSailID(), b.getColor()); + CompetitorDTO competitorDTO = new CompetitorDTOImpl(c.getName(), c.getShortName(), c.getColor(), c.getEmail(), c.getTwoLetterIsoCountryCode(), + c.getThreeLetterIocCountryCode(), + c.getCountryName(), + c.getIdAsString(), + c.getImageURL(), + c.getFlagImageURL(), + boatDTO, + boatClassDTO, + c.getTimeOnTimeFactor(), c.getTimeOnDistanceAllowancePerNauticalMile(), c.getSearchTag()); + + return competitorDTO; + } + @Override public void allowCompetitorResetToDefaults(Competitor competitor) { LockUtil.lockForWrite(lock); diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/FetchTracksAndStoreLocallyTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/FetchTracksAndStoreLocallyTest.java index ec229e6350c..8ccd78f5069 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/FetchTracksAndStoreLocallyTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/FetchTracksAndStoreLocallyTest.java @@ -10,6 +10,7 @@ import java.util.Map; import org.junit.Ignore; import org.junit.Test; +import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl; @@ -159,8 +160,9 @@ public class FetchTracksAndStoreLocallyTest extends OnlineTracTracBasedTest { private void storeTracks() throws FileNotFoundException, IOException { for (Map.Entry> competitorAndTrack : tracks.entrySet()) { Competitor competitor = competitorAndTrack.getKey(); + Boat boatOfCompetitor = trackedRace.getRace().getBoatOfCompetitorById(competitor); DynamicGPSFixTrack track = competitorAndTrack.getValue(); - storeTrack(competitor, track, getTracTracEvent().getName()+"-"+trackedRace.getRace().getName()); + storeTrack(competitor, boatOfCompetitor, track, getTracTracEvent().getName()+"-"+trackedRace.getRace().getName()); } } diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/DomainFactory.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/DomainFactory.java index 9f8e9f08003..d53c5ce9122 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/DomainFactory.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/DomainFactory.java @@ -77,9 +77,9 @@ public interface DomainFactory { Sideline createSideline(String name, Iterable controlPoints); - com.sap.sailing.domain.base.Competitor getOrCreateCompetitor(ICompetitor competitor); + com.sap.sailing.domain.base.CompetitorAndBoat getOrCreateCompetitorAndBoat(ICompetitor competitor); - com.sap.sailing.domain.base.Competitor getOrCreateCompetitor(UUID competitorId, String competitorClassName, + com.sap.sailing.domain.base.CompetitorAndBoat getOrCreateCompetitorAndBoat(UUID competitorId, String competitorClassName, String nationalityAsString, String name, String shortName, float timeOnTimeFactor, float timeOnDistanceAllowanceInSecondsPerNauticalMile, String searchTag); /** diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java index 069777680cc..cde248f48c1 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java @@ -26,6 +26,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorAndBoat; import com.sap.sailing.domain.base.CompetitorStore; import com.sap.sailing.domain.base.ControlPoint; import com.sap.sailing.domain.base.Course; @@ -35,7 +36,7 @@ import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Sideline; import com.sap.sailing.domain.base.Waypoint; -import com.sap.sailing.domain.base.impl.BoatImpl; +import com.sap.sailing.domain.base.impl.CompetitorAndBoatImpl; import com.sap.sailing.domain.base.impl.CourseImpl; import com.sap.sailing.domain.base.impl.DynamicPerson; import com.sap.sailing.domain.base.impl.DynamicTeam; @@ -73,6 +74,7 @@ import com.sap.sailing.domain.tractracadapter.ReceiverType; import com.sap.sailing.domain.tractracadapter.TracTracConfiguration; import com.sap.sailing.domain.tractracadapter.TracTracControlPoint; import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker; +import com.sap.sse.common.Color; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -233,24 +235,25 @@ public class DomainFactoryImpl implements DomainFactory { } @Override - public Competitor getOrCreateCompetitor(ICompetitor competitor) { + public CompetitorAndBoat getOrCreateCompetitorAndBoat(ICompetitor competitor) { final UUID competitorId = competitor.getId(); final String competitorClassName = competitor.getCompetitorClass()==null?null:competitor.getCompetitorClass().getName(); final String nationalityAsString = competitor.getNationality(); final String name = competitor.getName(); final String shortName = competitor.getShortName(); - Competitor result = getOrCreateCompetitor(competitorId, competitorClassName, nationalityAsString, name, + CompetitorAndBoat result = getOrCreateCompetitorAndBoat(competitorId, competitorClassName, nationalityAsString, name, shortName, competitor.getHandicapToT(), competitor.getHandicapToD(), null); return result; } @Override - public Competitor getOrCreateCompetitor(final UUID competitorId, final String competitorClassName, + public CompetitorAndBoat getOrCreateCompetitorAndBoat(final UUID competitorId, final String competitorClassName, final String nationalityAsString, final String name, final String shortName, float timeOnTimeFactor, float timeOnDistanceAllowanceInSecondsPerNauticalMile, String searchTag) { CompetitorStore competitorStore = baseDomainFactory.getCompetitorStore(); - Competitor result = competitorStore.getExistingCompetitorById(competitorId); - if (result == null || competitorStore.isCompetitorToUpdateDuringGetOrCreate(result)) { + Competitor domainCompetitor = competitorStore.getExistingCompetitorById(competitorId); + Boat domainBoat = competitorStore.getExistingBoatById(competitorId); + if (domainCompetitor == null || competitorStore.isCompetitorToUpdateDuringGetOrCreate(domainCompetitor)) { Nationality nationality; try { nationality = getOrCreateNationality(nationalityAsString); @@ -260,11 +263,17 @@ public class DomainFactoryImpl implements DomainFactory { logger.log(Level.SEVERE, "Unknown nationality "+nationalityAsString+" for competitor "+name+"; leaving null", iae); } DynamicTeam team = createTeam(name, nationality, competitorId); - result = competitorStore.getOrCreateCompetitor(competitorId, name, shortName, null /* displayColor */, + domainCompetitor = competitorStore.getOrCreateCompetitor(competitorId, name, shortName, null /* displayColor */, null /* email */, null /* flagImag */, team, (double) timeOnTimeFactor, new MillisecondsDurationImpl((long) (timeOnDistanceAllowanceInSecondsPerNauticalMile*1000)), searchTag); } - return result; + return new CompetitorAndBoatImpl(domainCompetitor, domainBoat); + } + + private Boat getOrCreateBoat(Serializable competitorId, Serializable boatId, String boatName, BoatClass boatClass, String sailId, Color boatColor) { + CompetitorStore competitorAndBoatStore = baseDomainFactory.getCompetitorStore(); + Boat boat = competitorAndBoatStore.getOrCreateBoat(competitorId, boatName, boatClass, sailId, boatColor); + return boat; } private DynamicTeam createTeam(String name, Nationality nationality, UUID competitorId) { @@ -594,9 +603,10 @@ public class DomainFactoryImpl implements DomainFactory { final Map competitorBoatInfos = new HashMap<>(); for (IRaceCompetitor rc : race.getRaceCompetitors()) { Util.Triple competitorBoatInfo = getMetadataParser().parseCompetitorBoat(rc); - Competitor existingCompetitor = getOrCreateCompetitor(rc.getCompetitor()); + CompetitorAndBoat existingCompetitorAndBoat = getOrCreateCompetitorAndBoat(rc.getCompetitor()); + Competitor existingCompetitor = existingCompetitorAndBoat.getCompetitor(); if (existingCompetitor != null && competitorBoatInfo != null) { - Boat boatOfCompetitor = new BoatImpl(competitorBoatInfo.getB(), + Boat boatOfCompetitor = getOrCreateBoat(existingCompetitor.getId(), competitorBoatInfo.getB(), competitorBoatInfo.getA(), defaultBoatClass, null, AbstractColor.getCssColor(competitorBoatInfo.getC())); competitorBoatInfos.put(existingCompetitor, boatOfCompetitor); } @@ -612,7 +622,7 @@ public class DomainFactoryImpl implements DomainFactory { for (IRaceCompetitor rc : race.getRaceCompetitors()) { // also add those whose race class doesn't match the dominant one (such as camera boats) // because they may still send data that we would like to record in some tracks - competitors.add(getOrCreateCompetitor(rc.getCompetitor())); + competitors.add(getOrCreateCompetitorAndBoat(rc.getCompetitor()).getCompetitor()); competitorClasses.add(rc.getCompetitor().getCompetitorClass()); } BoatClass dominantBoatClass = getDominantBoatClass(competitorClasses); diff --git a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/MarkPassingReceiver.java b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/MarkPassingReceiver.java index 96b25bbbca3..0aac8f92c8b 100755 --- a/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/MarkPassingReceiver.java +++ b/java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/MarkPassingReceiver.java @@ -69,11 +69,11 @@ public class MarkPassingReceiver extends AbstractReceiverWithQueue REMOVE later on */ CompetitorDTO convertToCompetitorDTO(Competitor c); + CompetitorDTO convertToCompetitorDTO(Competitor c, Boat b); + + CompetitorWithoutBoatDTO convertToCompetitorWithoutBoatDTO(Competitor c); + BoatDTO convertToBoatDTO(Boat boat); FleetDTO convertToFleetDTO(Fleet fleet); @@ -69,7 +77,12 @@ public interface DomainFactory extends SharedDomainFactory { PlacemarkDTO convertToPlacemarkDTO(Placemark placemark); - List getCompetitorDTOList(List competitors); + List getCompetitorDTOList(List competitors); + + /** Temporary function -> REMOVE later on */ + List getCompetitorWithoutBoatDTOListTemp(List competitors); + + List getCompetitorDTOListTemp(List competitors); TrackedRaceDTO createTrackedRaceDTO(TrackedRace trackedRace); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java index de60e758c8f..138eec9bd1e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java @@ -22,6 +22,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RegisteredCompetitorsAnalyzer; +import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RegisteredCompetitorsAndBoatsAnalyzer; import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogRegisterCompetitorEventImpl; import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogUseCompetitorsFromRaceLogEventImpl; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; @@ -296,8 +297,7 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem // race exists, its competitors set takes precedence over what's in the race log. Usually, // the tracked race will have the same competitors as those in the race log, or more because // those from the regatta log are added to the tracked race as well. - Set viaRaceLog = new RegisteredCompetitorsAnalyzer(getRaceLog(fleet), getRegattaLog()).analyze(); - result = viaRaceLog; + result = new RegisteredCompetitorsAndBoatsAnalyzer(getRaceLog(fleet), getRegattaLog()).analyze(); } return result; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java index 66e512243b6..2c38cc3e6a1 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java @@ -11,6 +11,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.CompetitorStore; +import com.sap.sailing.domain.base.CompetitorWithBoat; import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.Mark; @@ -26,6 +27,7 @@ import com.sap.sailing.domain.common.ScoringSchemeType; import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.dto.BoatDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.PlacemarkDTO; import com.sap.sailing.domain.common.dto.PlacemarkOrderDTO; @@ -48,10 +50,10 @@ import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets12Or8AndLastBre import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets12Or8AndLastBreaksTie2017; import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets1LastBreaksTie; import com.sap.sailing.domain.leaderboard.impl.HighPointLastBreaksTie; +import com.sap.sailing.domain.leaderboard.impl.HighPointMatchRacing; import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsEight; import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsEightAndInterpolation; import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsFive; -import com.sap.sailing.domain.leaderboard.impl.HighPointMatchRacing; import com.sap.sailing.domain.leaderboard.impl.HighPointWinnerGetsSix; import com.sap.sailing.domain.leaderboard.impl.LowPoint; import com.sap.sailing.domain.leaderboard.impl.LowPointForLeagueOverallLeaderboard; @@ -140,10 +142,25 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain } @Override - public CompetitorDTO convertToCompetitorDTO(Competitor c) { + public CompetitorDTO convertToCompetitorDTO(Competitor competitor) { + return competitorAndBoatStore.convertToCompetitorDTO(competitor, null); + } + + @Override + public CompetitorDTO convertToCompetitorDTO(Competitor competitor, Boat boat) { + return competitorAndBoatStore.convertToCompetitorDTO(competitor, boat); + } + + @Override + public CompetitorDTO convertToCompetitorDTO(CompetitorWithBoat c) { return competitorAndBoatStore.convertToCompetitorDTO(c); } + @Override + public CompetitorWithoutBoatDTO convertToCompetitorWithoutBoatDTO(Competitor c) { + return competitorAndBoatStore.convertToCompetitorWithoutBoatDTO(c); + } + @Override public BoatDTO convertToBoatDTO(Boat boat) { return competitorAndBoatStore.convertToBoatDTO(boat); @@ -196,6 +213,7 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain // GPS data statisticsDTO.hasGPSData = trackedRace.hasGPSData(); Competitor leaderOrWinner = null; + Boat leaderOrWinnerBoat = null; TimePoint now = MillisecondsTimePoint.now(); try { if (trackedRace.isLive(now)) { @@ -205,13 +223,14 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain Fleet fleetOfCompetitor = raceColumn.getFleetOfCompetitor(competitor); if (fleetOfCompetitor != null && fleetOfCompetitor.equals(fleet)) { leaderOrWinner = competitor; + leaderOrWinnerBoat = trackedRace.getBoatOfCompetitor(leaderOrWinner); break; } } } if (leaderOrWinner != null) { statisticsDTO.hasLeaderOrWinnerData = true; - statisticsDTO.leaderOrWinner = convertToCompetitorDTO(leaderOrWinner); + statisticsDTO.leaderOrWinner = convertToCompetitorDTO(leaderOrWinner, leaderOrWinnerBoat); GPSFixTrack track = trackedRace.getTrack(leaderOrWinner); if (track != null) { statisticsDTO.averageGPSDataSampleInterval = track.getAverageIntervalBetweenRawFixes(); @@ -345,12 +364,29 @@ public class DomainFactoryImpl extends SharedDomainFactoryImpl implements Domain } @Override - public List getCompetitorDTOList(List competitors) { + public List getCompetitorDTOList(List competitors) { + List result = new ArrayList(); + for (CompetitorWithBoat competitor : competitors) { + result.add(convertToCompetitorDTO(competitor)); + } + return result; + } + + @Override + public List getCompetitorDTOListTemp(List competitors) { List result = new ArrayList(); for (Competitor competitor : competitors) { result.add(convertToCompetitorDTO(competitor)); } return result; } - + + @Override + public List getCompetitorWithoutBoatDTOListTemp(List competitors) { + List result = new ArrayList(); + for (Competitor competitor : competitors) { + result.add(convertToCompetitorWithoutBoatDTO(competitor)); + } + return result; + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java index 55ac0fcd741..811a3b17436 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java @@ -25,6 +25,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEven import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -134,6 +135,11 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali notifyOnAdd(event); } + @Override + public void visit(RaceLogRegisterCompetitorAndBoatEvent event) { + notifyOnAdd(event); + } + @Override public void visit(RaceLogFixedMarkPassingEvent event) { notifyOnAdd(event); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java index 5373f460c06..7f5888970ae 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/Leaderboard.java @@ -133,7 +133,7 @@ public interface Leaderboard extends LeaderboardBase, HasRaceColumns { void setSuppressed(Competitor competitor, boolean suppressed); /** - * Retrieves the boat for a given competitor. + * Retrieves the boat of a given competitor for the specified raceColumn and fleet. */ Boat getBoatOfCompetitor(Competitor competitor, RaceColumn raceColumn, Fleet fleet); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index b071a65050c..cc69753aed7 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -2,7 +2,6 @@ package com.sap.sailing.domain.leaderboard.impl; import java.io.IOException; import java.io.ObjectInputStream; -import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -35,6 +34,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorWithBoat; import com.sap.sailing.domain.base.Course; import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.Fleet; @@ -57,6 +57,7 @@ import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.SpeedWithBearing; import com.sap.sailing.domain.common.dto.BasicRaceDTO; import com.sap.sailing.domain.common.dto.CompetitorDTO; +import com.sap.sailing.domain.common.dto.CompetitorWithoutBoatDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.LeaderboardDTO; import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO; @@ -1307,8 +1308,10 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null, fleetDTO, raceColumn.isMedalRace(), raceIdentifier, race, isMetaLeaderboardColumn); } + // List getCompetitorWithoutBoatDTOList(List competitors); + // List getCompetitorDTOList(List competitors); Future> task = executor.submit( - () -> baseDomainFactory.getCompetitorDTOList(AbstractSimpleLeaderboardImpl.this.getCompetitorsFromBestToWorst(raceColumn, timePoint))); + () -> baseDomainFactory.getCompetitorDTOListTemp(AbstractSimpleLeaderboardImpl.this.getCompetitorsFromBestToWorst(raceColumn, timePoint))); competitorsFromBestToWorstTasks.put(raceColumn, task); } // wait for the competitor orderings to have been computed for all race columns before continuing; subsequent tasks may depend on these data @@ -2012,8 +2015,13 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race @Override public BoatClass getBoatClass() { - return Util.getDominantObject(StreamSupport.stream(getCompetitors().spliterator(), /* parallel */ false). - map(c->c.getBoat().getBoatClass()).collect(Collectors.toList())); + Set allBoats = new HashSet<>(); + for (final RaceColumn raceColumn : getRaceColumns()) { + Map competitorsAndTheirBoats = raceColumn.getAllCompetitorsAndTheirBoats(); + allBoats.addAll(competitorsAndTheirBoats.values()); + } + return Util.getDominantObject(StreamSupport.stream(allBoats.spliterator(), /* parallel */ false). + map(b->b.getBoatClass()).collect(Collectors.toList())); } protected abstract LeaderboardType getLeaderboardType(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java index fe075435790..4e464ccd500 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java @@ -15,13 +15,11 @@ import java.util.logging.Logger; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; -import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceColumnListener; -import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.impl.AbstractRaceExecutionOrderProvider; import com.sap.sailing.domain.base.impl.RegattaLogEventAdditionForwarder; @@ -110,7 +108,7 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements this.regattaLikeHelper.addListener(new RegattaLogEventAdditionForwarder(getRaceColumnListeners())); this.raceExecutionOrderProvider = new RaceExecutionOrderCache(); } - + /** * Deserialization has to be maintained in lock-step with {@link #writeObject(ObjectOutputStream) serialization}. * When de-serializing, a possibly remote {@link #raceLogStore} is ignored because it is transient. Instead, an diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java index 85f2cfa40fe..46ca0ff849a 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java @@ -1,10 +1,12 @@ package com.sap.sailing.domain.leaderboard.meta; import java.util.Collections; +import java.util.Map; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; +import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.Mark; @@ -284,4 +286,16 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R @Override public void disableCompetitorRegistrationOnRaceLog(Fleet fleetByName) { } + + @Override + public Map getAllCompetitorsAndTheirBoats() { + // TODO: What should we do here? Returning a boat makes only sense when the competitors keep their boats through all regattas + return Collections.emptyMap(); + } + + @Override + public Map getAllCompetitorsAndTheirBoats(Fleet fleet) { + // TODO: What should we do here? Returning a boat makes only sense when the competitors keep their boats through all regattas + return Collections.emptyMap(); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/SimpleCompetitorDTO.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/SimpleCompetitorDTO.java index ebde9a2c6af..9890e1e95ee 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/SimpleCompetitorDTO.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/event/SimpleCompetitorDTO.java @@ -4,6 +4,7 @@ import java.io.Serializable; import com.google.gwt.core.shared.GwtIncompatible; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorWithBoat; import com.sap.sailing.domain.base.Nationality; import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.NamedDTO; @@ -22,13 +23,17 @@ public class SimpleCompetitorDTO extends NamedDTO implements DTO, Serializable, } @GwtIncompatible - public SimpleCompetitorDTO(Competitor competitor) { + public SimpleCompetitorDTO(C competitor) { super(competitor.getName()); final Nationality nationality = competitor.getTeam().getNationality(); CountryCode countryCode = nationality == null ? null : nationality.getCountryCode(); - this.sailID = competitor.getBoat().getSailID(); this.twoLetterIsoCountryCode = countryCode == null ? null : countryCode.getTwoLetterISOCode(); this.flagImageURL = competitor.getFlagImage() == null ? null : competitor.getFlagImage().toString(); + if (competitor instanceof CompetitorWithBoat) { + this.sailID = ((CompetitorWithBoat) competitor).getBoat().getSailID(); + } else { + this.sailID = null; + } } @GwtIncompatible diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/user/profile/GetCompetitorSuggestionAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/user/profile/GetCompetitorSuggestionAction.java index 8b70fe591f4..e3a7dd6aadb 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/user/profile/GetCompetitorSuggestionAction.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/communication/user/profile/GetCompetitorSuggestionAction.java @@ -31,8 +31,7 @@ public class GetCompetitorSuggestionAction implements SailingAction competitorFilter = new AbstractListFilter() { @Override public Iterable getStrings(Competitor competitor) { - if (competitor.getBoat() == null) return Arrays.asList(competitor.getName()); - return Arrays.asList(competitor.getBoat().getSailID(), competitor.getName()); + return Arrays.asList(competitor.getName()); } }; diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java index 92499203998..9ac3ed86858 100755 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndRetrievingLeaderboardGroups.java @@ -25,8 +25,8 @@ import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.impl.BoatClassImpl; import com.sap.sailing.domain.base.impl.BoatImpl; -import com.sap.sailing.domain.base.impl.CompetitorImpl; import com.sap.sailing.domain.base.impl.CompetitorAndBoatImpl; +import com.sap.sailing.domain.base.impl.CompetitorImpl; import com.sap.sailing.domain.base.impl.NationalityImpl; import com.sap.sailing.domain.base.impl.PersonImpl; import com.sap.sailing.domain.base.impl.TeamImpl; diff --git a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java index 9f466062a45..33cd593911b 100644 --- a/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization.shared.android/src/com/sap/sailing/server/gateway/serialization/racelog/impl/RaceLogEventSerializer.java @@ -25,6 +25,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEven import com.sap.sailing.domain.abstractlog.race.RaceLogWindFixEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; +import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorAndBoatEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFromRaceLogEvent; @@ -258,11 +259,17 @@ public class RaceLogEventSerializer implements JsonSerializer, Rac public void visit(RaceLogRevokeEvent event) { chosenSerializer = revokeSerializer; } + @Override public void visit(RaceLogRegisterCompetitorEvent event) { chosenSerializer = registerCompetitorSerializer; } - + + @Override + public void visit(RaceLogRegisterCompetitorAndBoatEvent event) { + chosenSerializer = registerCompetitorSerializer; + } + @Override public void visit(RaceLogAdditionalScoringInformationEvent additionalScoringInformation) { chosenSerializer = additionalScoringInformationSerializer; diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java index 2c49145e136..50efe111107 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java @@ -43,7 +43,6 @@ import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpe import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl; import com.sap.sailing.domain.abstractlog.regatta.impl.OpenEndedDeviceMappingFinder; -import com.sap.sailing.domain.base.Boat; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.Fleet; @@ -230,12 +229,10 @@ public class LeaderboardsResource extends AbstractSailingServerResource { for (Competitor competitor : leaderboard.getCompetitors()) { JSONObject jsonCompetitor = new JSONObject(); jsonCompetitor.put("name", competitor.getName()); + jsonCompetitor.put("shortName", competitor.getShortName()); final String displayName = leaderboard.getDisplayName(competitor); jsonCompetitor.put("displayName", displayName == null ? competitor.getName() : displayName); jsonCompetitor.put("id", competitor.getId().toString()); - final Boat boatOfCompetitor = leaderboard.getBoatOfCompetitor(competitor); - final String sailID = boatOfCompetitor != null ? boatOfCompetitor.getSailID() : null; - jsonCompetitor.put("sailID", sailID); Nationality nationality = competitor.getTeam().getNationality(); jsonCompetitor.put("nationality", nationality != null ? nationality.getThreeLetterIOCAcronym() : null); jsonCompetitor.put("countryCode", nationality != null ? (nationality.getCountryCode() != null ? nationality diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RegattaByKeywordSearchService.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RegattaByKeywordSearchService.java index 2b9b9d93488..0c501a4abcd 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RegattaByKeywordSearchService.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RegattaByKeywordSearchService.java @@ -72,7 +72,7 @@ public class RegattaByKeywordSearchService { leaderboardStrings.add(leaderboard.getDisplayName()); for (Competitor competitor : leaderboard.getCompetitors()) { leaderboardStrings.add(competitor.getName()); - leaderboardStrings.add(competitor.getBoat().getSailID()); + leaderboardStrings.add(competitor.getShortName()); String competitorDisplayName = leaderboard.getDisplayName(competitor); if (competitorDisplayName != null) { leaderboardStrings.add(competitorDisplayName); diff --git a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java index fd551388994..46fcd6cfac1 100644 --- a/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java +++ b/java/com.sap.sailing.xmlexport/src/com/sap/sailing/xmlexport/LeaderboardData.java @@ -238,7 +238,8 @@ public class LeaderboardData extends ExportAction { MaxPointsReason mpr = leaderboard.getScoreCorrection().getMaxPointsReason(competitorInLeaderboard, column, timepointToBeUsed); if (mpr != null && !mpr.equals(MaxPointsReason.NONE)) { // add this competitor to the list to have him evaluated - Element competitorElement = createCompetitorXML(competitorInLeaderboard, leaderboard, /*shortVersion*/ true, null); + Boat boatOfCompetitor = null; // TODO: Where can we get the boat here? + Element competitorElement = createCompetitorXML(competitorInLeaderboard, boatOfCompetitor, leaderboard, /*shortVersion*/ true, null); Element competitorRaceDataElement = new Element("competitor_race_data"); MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitorInLeaderboard, column, timepointToBeUsed); addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", maxPointsReason.toString()); @@ -399,7 +400,8 @@ public class LeaderboardData extends ExportAction { if (fleetCompetitorIsSailingIn != null && fleetCompetitorIsSailingIn.equals(fleet) && !competitorsForColumn.contains(competitorInLeaderboard)) { if (mpr != null && !mpr.equals(MaxPointsReason.NONE)) { // add this competitor to the list to have him evaluated - Element competitorElement = createCompetitorXML(competitorInLeaderboard, leaderboard, /*shortVersion*/ true, null); + Boat boatOfCompetitor = leaderboard.getBoatOfCompetitor(competitorInLeaderboard, column, fleetCompetitorIsSailingIn); + Element competitorElement = createCompetitorXML(competitorInLeaderboard, boatOfCompetitor, leaderboard, /*shortVersion*/ true, null); Element competitorRaceDataElement = new Element("competitor_race_data"); MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitorInLeaderboard, column, race.getEndOfRace()); addNamedElementWithValue(competitorRaceDataElement, "max_points_reason", maxPointsReason.toString()); @@ -420,7 +422,8 @@ public class LeaderboardData extends ExportAction { int raceRank = 0; for (Competitor competitor : allCompetitors) { - Element competitorElement = createCompetitorXML(competitor, leaderboard, /*shortVersion*/ true, null); + Boat boatOfCompetitor = null; // TODO: Where can we get the boat here? + Element competitorElement = createCompetitorXML(competitor, boatOfCompetitor, leaderboard, /*shortVersion*/ true, null); Element competitorRaceDataElement = new Element("competitor_race_data"); MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitor, column, race.getEndOfRace()); if (maxPointsReason != null && !maxPointsReason.equals(MaxPointsReason.NONE)) { @@ -620,7 +623,8 @@ public class LeaderboardData extends ExportAction { * Creates xml elements related to a competitor. * @param shortVersion when set to true then only the name and UUID is returned */ - private Element createCompetitorXML(Competitor competitor, Leaderboard leaderboard, boolean shortVersion, Util.Pair> competitorConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException { + private Element createCompetitorXML(Competitor competitor, Boat boatOfCompetitor, Leaderboard leaderboard, + boolean shortVersion, Util.Pair> competitorConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException { TimePoint timeSpent = MillisecondsTimePoint.now(); Element competitorElement = new Element("competitor"); addNamedElementWithValue(competitorElement, "uuid", competitor.getId().toString()); @@ -629,7 +633,6 @@ public class LeaderboardData extends ExportAction { if (shortVersion) return competitorElement; - final Boat boatOfCompetitor = leaderboard.getBoatOfCompetitor(competitor); if (boatOfCompetitor != null) { addNamedElementWithValue(competitorElement, "sail_id", cleanSailId(boatOfCompetitor.getSailID(), competitor)); addNamedElementWithValue(competitorElement, "boat_class", boatOfCompetitor.getBoatClass().getName()); @@ -732,7 +735,8 @@ public class LeaderboardData extends ExportAction { addNamedElementWithValue(legElement, "great_circle_distance_at_end_of_race_in_meters", trackedLeg.getGreatCircleDistance(trackedLeg.getTrackedRace().getEndOfRace()).getMeters()); for (Competitor competitor : trackedLeg.getTrackedRace().getCompetitorsFromBestToWorst(/*timePoint*/ trackedLeg.getTrackedRace().getEndOfRace())) { - Element competitorElement = createCompetitorXML(competitor, leaderboard, /*shortVersion*/ true, null); + Boat boatOfCompetitor = null; // TODO: Where can we get the boat here? + Element competitorElement = createCompetitorXML(competitor, boatOfCompetitor, leaderboard, /*shortVersion*/ true, null); Element competitorLegDataElement = new Element("competitor_leg_data"); TrackedLegOfCompetitor competitorLeg = trackedLeg.getTrackedLeg(competitor); @@ -1031,9 +1035,9 @@ public class LeaderboardData extends ExportAction { final List racesElements = new ArrayList(); final List competitorElements = new ArrayList(); for (Competitor competitor : leaderboard.getAllCompetitors()) { - Boat boatOfCompetitor = leaderboard.getBoatOfCompetitor(competitor); + Boat boatOfCompetitor = null; // TODO: Where can we get the boat here? Util.Pair> competitorConfidenceAndErrorMessages = checkData(competitor, boatOfCompetitor); - competitorElements.add(createCompetitorXML(competitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages)); + competitorElements.add(createCompetitorXML(competitor, boatOfCompetitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages)); } List windData = new ArrayList(); TrackedRace raceBefore = null; int sameDayGroupIndex = 0; int raceCounter = 0; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java index 188d3ebec8d..f406fcf140a 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java @@ -8,12 +8,6 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.Callable; -import android.app.LoaderManager.LoaderCallbacks; -import android.content.Context; -import android.content.Loader; -import android.os.Bundle; -import android.util.Log; - import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.services.sending.MessageSendingService; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; @@ -66,9 +60,7 @@ import com.sap.sailing.server.gateway.deserialization.coursedata.impl.CourseBase import com.sap.sailing.server.gateway.deserialization.coursedata.impl.GateDeserializer; import com.sap.sailing.server.gateway.deserialization.coursedata.impl.MarkDeserializer; import com.sap.sailing.server.gateway.deserialization.coursedata.impl.WaypointDeserializer; -import com.sap.sailing.server.gateway.deserialization.impl.BoatClassJsonDeserializer; -import com.sap.sailing.server.gateway.deserialization.impl.BoatJsonDeserializer; -import com.sap.sailing.server.gateway.deserialization.impl.CompetitorWithBoatJsonDeserializer; +import com.sap.sailing.server.gateway.deserialization.impl.CompetitorJsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.DeviceConfigurationJsonDeserializer; import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer; @@ -82,6 +74,12 @@ import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer import com.sap.sailing.server.gateway.deserialization.racegroup.impl.RaceGroupDeserializer; import com.sap.sse.common.Util; +import android.app.LoaderManager.LoaderCallbacks; +import android.content.Context; +import android.content.Loader; +import android.os.Bundle; +import android.util.Log; + /** * Enables accessing of data. */ @@ -248,9 +246,8 @@ public class OnlineDataManager extends DataManager { @Override public Loader>> create(int id, Bundle args) throws Exception { ExLog.i(context, TAG, "Creating Competitor-OnlineDataLoader " + id); - JsonDeserializer competitorDeserializer = new CompetitorWithBoatJsonDeserializer(domainFactory.getCompetitorStore(), - new TeamJsonDeserializer(new PersonJsonDeserializer(new NationalityJsonDeserializer(domainFactory))), - new BoatJsonDeserializer(domainFactory, new BoatClassJsonDeserializer(domainFactory))); + JsonDeserializer competitorDeserializer = new CompetitorJsonDeserializer(domainFactory.getCompetitorStore(), + new TeamJsonDeserializer(new PersonJsonDeserializer(new NationalityJsonDeserializer(domainFactory)))); DataParser> parser = new CompetitorsDataParser(competitorDeserializer); DataHandler> handler = new CompetitorsDataHandler(OnlineDataManager.this, managedRace); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/CompetitorAdapter.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/CompetitorAdapter.java index 4f83900400d..1627cd9aef1 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/CompetitorAdapter.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/adapters/CompetitorAdapter.java @@ -39,8 +39,11 @@ public class CompetitorAdapter extends RecyclerView.Adapter { @@ -14,17 +16,24 @@ public class CompetitorSailIdComparator implements Comparator { } @Override - public int compare(Competitor left, Competitor right) { - // if left is null, right will be greater - if (left == null || left.getBoat() == null || left.getBoat().getSailID() == null) { - return -1; - } + public int compare(Competitor leftCompetitor, Competitor rightCompetitor) { + if (leftCompetitor != null && leftCompetitor instanceof CompetitorWithBoat && + rightCompetitor != null && rightCompetitor instanceof CompetitorWithBoat) { + Boat leftBoat = ((CompetitorWithBoat) leftCompetitor).getBoat(); + Boat rightBoat = ((CompetitorWithBoat) rightCompetitor).getBoat(); + + // if left is null, right will be greater + if (leftBoat == null || leftBoat.getSailID() == null) { + return -1; + } - // if right is null, left will be greater - if (right == null || right.getBoat() == null || right.getBoat().getSailID() == null) { - return 1; - } + // if right is null, left will be greater + if (rightBoat == null || rightBoat.getSailID() == null) { + return 1; + } - return comparator.compare(left.getBoat().getSailID(), right.getBoat().getSailID()); + return comparator.compare(leftBoat.getSailID(), rightBoat.getSailID()); + } + return 0; } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/TrackingListFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/TrackingListFragment.java index 1c6ace1b64c..2c31be255e2 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/TrackingListFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/TrackingListFragment.java @@ -6,6 +6,39 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator; +import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager; +import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager; +import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager; +import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; +import com.sap.sailing.android.shared.util.AppUtils; +import com.sap.sailing.android.shared.util.ViewHelper; +import com.sap.sailing.domain.abstractlog.race.CompetitorResult; +import com.sap.sailing.domain.abstractlog.race.CompetitorResults; +import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultImpl; +import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultsImpl; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.CompetitorStore; +import com.sap.sailing.domain.base.CompetitorWithBoat; +import com.sap.sailing.domain.base.SharedDomainFactory; +import com.sap.sailing.domain.common.MaxPointsReason; +import com.sap.sailing.racecommittee.app.AppConstants; +import com.sap.sailing.racecommittee.app.R; +import com.sap.sailing.racecommittee.app.data.DataManager; +import com.sap.sailing.racecommittee.app.data.OnlineDataManager; +import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager; +import com.sap.sailing.racecommittee.app.data.clients.LoadClient; +import com.sap.sailing.racecommittee.app.domain.impl.CompetitorResultWithIdImpl; +import com.sap.sailing.racecommittee.app.ui.adapters.CompetitorAdapter; +import com.sap.sailing.racecommittee.app.ui.adapters.FinishListAdapter; +import com.sap.sailing.racecommittee.app.ui.adapters.StringArraySpinnerAdapter; +import com.sap.sailing.racecommittee.app.ui.comparators.CompetitorSailIdComparator; +import com.sap.sailing.racecommittee.app.ui.comparators.NaturalNamedComparator; +import com.sap.sailing.racecommittee.app.ui.layouts.CompetitorEditLayout; +import com.sap.sailing.racecommittee.app.ui.layouts.HeaderLayout; +import com.sap.sse.common.Util; +import com.sap.sse.common.impl.MillisecondsTimePoint; + import android.content.Context; import android.content.DialogInterface; import android.content.Loader; @@ -27,38 +60,6 @@ import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; -import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator; -import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager; -import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager; -import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager; -import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; -import com.sap.sailing.android.shared.util.AppUtils; -import com.sap.sailing.android.shared.util.ViewHelper; -import com.sap.sailing.domain.abstractlog.race.CompetitorResult; -import com.sap.sailing.domain.abstractlog.race.CompetitorResults; -import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultImpl; -import com.sap.sailing.domain.abstractlog.race.impl.CompetitorResultsImpl; -import com.sap.sailing.domain.base.Competitor; -import com.sap.sailing.domain.base.CompetitorStore; -import com.sap.sailing.domain.base.SharedDomainFactory; -import com.sap.sailing.domain.common.MaxPointsReason; -import com.sap.sailing.racecommittee.app.AppConstants; -import com.sap.sailing.racecommittee.app.R; -import com.sap.sailing.racecommittee.app.data.DataManager; -import com.sap.sailing.racecommittee.app.data.OnlineDataManager; -import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager; -import com.sap.sailing.racecommittee.app.data.clients.LoadClient; -import com.sap.sailing.racecommittee.app.domain.impl.CompetitorResultWithIdImpl; -import com.sap.sailing.racecommittee.app.ui.adapters.CompetitorAdapter; -import com.sap.sailing.racecommittee.app.ui.adapters.FinishListAdapter; -import com.sap.sailing.racecommittee.app.ui.adapters.StringArraySpinnerAdapter; -import com.sap.sailing.racecommittee.app.ui.comparators.CompetitorSailIdComparator; -import com.sap.sailing.racecommittee.app.ui.comparators.NaturalNamedComparator; -import com.sap.sailing.racecommittee.app.ui.layouts.CompetitorEditLayout; -import com.sap.sailing.racecommittee.app.ui.layouts.HeaderLayout; -import com.sap.sse.common.Util; -import com.sap.sse.common.impl.MillisecondsTimePoint; - public class TrackingListFragment extends BaseFragment implements CompetitorAdapter.CompetitorClick, FinishListAdapter.FinishEvents, View.OnClickListener, AdapterView.OnItemSelectedListener { @@ -356,8 +357,11 @@ public class TrackingListFragment extends BaseFragment private void moveCompetitorToFinishList(Competitor competitor) { String name = ""; - if (competitor.getBoat() != null) { - name += competitor.getBoat().getSailID(); + if (competitor instanceof CompetitorWithBoat) { + CompetitorWithBoat competitorWithBoat = (CompetitorWithBoat) competitor; + if (competitorWithBoat.getBoat() != null) { + name += competitorWithBoat.getBoat().getSailID(); + } } name += " - " + competitor.getName(); mFinishedData.add(new CompetitorResultWithIdImpl(mId, competitor.getId(), name, mFinishedData.size() + 1, MaxPointsReason.NONE,