Next step of the removal of Competitor.getBoat()

As this affects also CompetitorDTO.getBoat() I introduced as an intermediate step CompetitorWithoutBoatDTO (CompetitorDTO extends CompetitorWithoutBoatDTO) for simpler refactoring.
Added also some new RaceLog and RegattaLog events for adding a competitor/boat pair
This commit is contained in:
Frank Mittag
2017-06-19 21:21:31 +02:00
parent fd8fee5d58
commit bc8a71f058
60 changed files with 1209 additions and 388 deletions
@@ -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<Leaderb
public LeaderboardCompetitorsDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
LeaderboardCompetitorsDTO result = new LeaderboardCompetitorsDTO();
Leaderboard lb = dashboardDispatchContext.getRacingEventService().getLeaderboardByName(this.leaderboarName);
result.setCompetitors(dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorDTOList(lb.getCompetitorsFromBestToWorst(MillisecondsTimePoint.now())));
List<Competitor> competitorsFromBestToWorst = lb.getCompetitorsFromBestToWorst(MillisecondsTimePoint.now());
List<CompetitorWithoutBoatDTO> competitorDTOs = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorWithoutBoatDTOListTemp(competitorsFromBestToWorst);
result.setCompetitors(competitorDTOs);
return result;
}
}
@@ -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);
}
@@ -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<CompetitorDTO> competitorList) {
public void show(List<CompetitorWithoutBoatDTO> 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;
}
@@ -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<CompetitorDTO> table;
private CellTable<CompetitorWithoutBoatDTO> table;
private CompetitorTableRowSelectionListener competitorTableRowSelectionListener;
public CompetitorTable(CompetitorTableRowSelectionListener competitorTableRowSelectionListener) {
this.competitorTableRowSelectionListener = competitorTableRowSelectionListener;
}
public void setTableContent(List<CompetitorDTO> competitorNames) {
public void setTableContent(List<CompetitorWithoutBoatDTO> competitorNames) {
if (table == null) {
initTable(competitorNames);
}
}
private void initTable(List<CompetitorDTO> competitorNames) {
private void initTable(List<CompetitorWithoutBoatDTO> competitorNames) {
CellTable.Resources tableRes = GWT.create(CompetitorTableStyleResource.class);
table = new BaseCelltable<CompetitorDTO>(15, tableRes);
table = new BaseCelltable<CompetitorWithoutBoatDTO>(15, tableRes);
table.getElement().getStyle().setWidth(100, Unit.PCT);
table.setSkipRowHoverStyleUpdate(true);
table.setSkipRowHoverCheck(true);
table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED);
final SingleSelectionModel<CompetitorDTO> selectionModel = new SingleSelectionModel<CompetitorDTO>();
final SingleSelectionModel<CompetitorWithoutBoatDTO> selectionModel = new SingleSelectionModel<CompetitorWithoutBoatDTO>();
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<CompetitorDTO> competitorNameCollumn = new TextColumn<CompetitorDTO>() {
TextColumn<CompetitorWithoutBoatDTO> competitorNameCollumn = new TextColumn<CompetitorWithoutBoatDTO>() {
@Override
public String getValue(CompetitorDTO competitor) {
public String getValue(CompetitorWithoutBoatDTO competitor) {
return competitor.getName();
}
};
@@ -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);
}
@@ -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));
@@ -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;
}
@@ -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<CompetitorDTO> competitors;
private List<CompetitorWithoutBoatDTO> competitors;
public LeaderboardCompetitorsDTO() {}
public List<CompetitorDTO> getCompetitors() {
public List<CompetitorWithoutBoatDTO> getCompetitors() {
return competitors;
}
public void setCompetitors(List<CompetitorDTO> competitors) {
public void setCompetitors(List<CompetitorWithoutBoatDTO> competitors) {
this.competitors = competitors;
}
}
@@ -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();
}
@@ -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
@@ -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();
}
@@ -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;
}
}
@@ -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<Competitor> 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<Competitor> 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(
@@ -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
@@ -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<DeviceIdentifierMongoHandler> deviceIdentifierServiceFinder;
private final TypeBasedServiceFinder<RaceTrackingConnectivityParametersHandler> 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());
@@ -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);
@@ -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);
@@ -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");
}
@@ -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);
@@ -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);
@@ -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) {
@@ -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<RaceLogEventVisitor> {
}
@@ -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<Map<Competitor, Boat>> {
private RegattaLog regattaLog;
public RegisteredCompetitorsAndBoatsAnalyzer(RaceLog raceLog, RegattaLog regattaLog) {
super(raceLog);
this.regattaLog = regattaLog;
}
@Override
protected Map<Competitor, Boat> performAnalysis() {
final Map<Competitor, Boat> 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;
}
}
@@ -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<RaceLogEventVisitor> 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<Competitor> getInvolvedBoats() {
return Collections.singletonList(getCompetitor());
}
@Override
public String toString() {
return raceLogEventData.toString();
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
}
@@ -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);
@@ -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<RegattaLogEventVisitor> {
}
@@ -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<RegattaLogEventVisitor>
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);
}
}
@@ -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) {
}
@@ -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);
@@ -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<LogT extends AbstractLog<EventT, VisitorT>, EventT extends AbstractLogEvent<VisitorT>, VisitorT>
extends BaseLogAnalyzer<LogT, EventT, VisitorT, Map<Competitor, Boat>> {
public CompetitorsAndBoatsInLogAnalyzer(LogT log) {
super(log);
}
@Override
protected Map<Competitor, Boat> performAnalysis() {
Map<Competitor, Boat> result = new HashMap<>();
for (EventT event : getLog().getUnrevokedEvents()) {
if (event instanceof RegisterCompetitorAndBoatEvent) {
RegisterCompetitorAndBoatEvent<?> competitorAndBoatEvent = (RegisterCompetitorAndBoatEvent<?>) event;
result.put(competitorAndBoatEvent.getCompetitor(), competitorAndBoatEvent.getBoat());
}
}
return result;
}
}
@@ -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<VisitorT> extends AbstractLogEvent<VisitorT>, Revokable {
Competitor getCompetitor();
Boat getBoat();
}
@@ -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<VisitorT> extends AbstractLogEventImpl<VisitorT> implements
RegisterCompetitorAndBoatEvent<VisitorT> {
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();
}
}
@@ -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<Competitor> 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.
@@ -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<CompetitorChangeListener> 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<CompetitorChangeListener>();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
listeners = new HashSet<CompetitorChangeListener>();
}
@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<CompetitorChangeListener> getListeners() {
synchronized (listeners) {
return new HashSet<CompetitorChangeListener>(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);
}
}
}
}
@@ -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<Competitor> competitorsToUpdateDuringGetOrCreate;
private transient WeakHashMap<Competitor, CompetitorDTO> weakCompetitorDTOCache;
private transient WeakHashMap<Competitor, CompetitorWithoutBoatDTO> weakCompetitorDTOCache;
private final Set<Boat> boatsToUpdateDuringGetOrCreate;
@@ -60,7 +63,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
competitorCache = new HashMap<Serializable, Competitor>();
competitorsByIdAsString = new HashMap<String, Competitor>();
competitorsToUpdateDuringGetOrCreate = new HashSet<Competitor>();
weakCompetitorDTOCache = new WeakHashMap<Competitor, CompetitorDTO>();
weakCompetitorDTOCache = new WeakHashMap<Competitor, CompetitorWithoutBoatDTO>();
competitorUpdateListeners = Collections.synchronizedSet(new HashSet<CompetitorStore.CompetitorUpdateListener>());
boatCache = new HashMap<Serializable, Boat>();
boatsByIdAsString = new HashMap<String, Boat>();
@@ -71,7 +74,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
weakCompetitorDTOCache = new WeakHashMap<Competitor, CompetitorDTO>();
weakCompetitorDTOCache = new WeakHashMap<Competitor, CompetitorWithoutBoatDTO>();
competitorUpdateListeners = Collections.synchronizedSet(new HashSet<CompetitorStore.CompetitorUpdateListener>());
weakBoatDTOCache = new WeakHashMap<Boat, BoatDTO>();
boatUpdateListeners = Collections.synchronizedSet(new HashSet<CompetitorStore.BoatUpdateListener>());
@@ -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);
@@ -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<Competitor, DynamicGPSFixTrack<Competitor, GPSFixMoving>> competitorAndTrack : tracks.entrySet()) {
Competitor competitor = competitorAndTrack.getKey();
Boat boatOfCompetitor = trackedRace.getRace().getBoatOfCompetitorById(competitor);
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = competitorAndTrack.getValue();
storeTrack(competitor, track, getTracTracEvent().getName()+"-"+trackedRace.getRace().getName());
storeTrack(competitor, boatOfCompetitor, track, getTracTracEvent().getName()+"-"+trackedRace.getRace().getName());
}
}
@@ -77,9 +77,9 @@ public interface DomainFactory {
Sideline createSideline(String name, Iterable<TracTracControlPoint> 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);
/**
@@ -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<Competitor, Boat> competitorBoatInfos = new HashMap<>();
for (IRaceCompetitor rc : race.getRaceCompetitors()) {
Util.Triple<String, String, String> 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);
@@ -69,11 +69,11 @@ public class MarkPassingReceiver extends AbstractReceiverWithQueue<IRaceCompetit
com.sap.sailing.domain.base.ControlPoint domainControlPoint = getDomainFactory()
.getOrCreateControlPoint(new ControlPointAdapter(controlPointPassed));
Waypoint passed = findWaypointForControlPoint(trackedRace, waypointsIter, domainControlPoint,
getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()));
getDomainFactory().getOrCreateCompetitorAndBoat(event.getA().getCompetitor()).getCompetitor());
if (passed != null) {
TimePoint time = new MillisecondsTimePoint(passing.getTimestamp());
MarkPassing markPassing = getDomainFactory().createMarkPassing(time, passed,
getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()));
getDomainFactory().getOrCreateCompetitorAndBoat(event.getA().getCompetitor()).getCompetitor());
passingsByWaypoint.put(passed, markPassing);
} else {
logger.warning("Didn't find waypoint in course " + course + " for mark passing around "
@@ -89,9 +89,9 @@ public class MarkPassingReceiver extends AbstractReceiverWithQueue<IRaceCompetit
}
logger.fine("Received mark passings in race "+trackedRace.getRace().getName()+": "+markPassings);
if (getSimulator() != null) {
getSimulator().delayMarkPassings(getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()), markPassings);
getSimulator().delayMarkPassings(getDomainFactory().getOrCreateCompetitorAndBoat(event.getA().getCompetitor()).getCompetitor(), markPassings);
} else {
trackedRace.updateMarkPassings(getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor()),
trackedRace.updateMarkPassings(getDomainFactory().getOrCreateCompetitorAndBoat(event.getA().getCompetitor()).getCompetitor(),
markPassings);
}
} else {
@@ -58,7 +58,7 @@ public class RawPositionReceiver extends AbstractReceiverWithQueue<IRaceCompetit
DynamicTrackedRace trackedRace = getTrackedRace(race);
if (trackedRace != null) {
final GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
Competitor competitor = getDomainFactory().getOrCreateCompetitorAndBoat(event.getA().getCompetitor()).getCompetitor();
if (getSimulator() != null) {
getSimulator().scheduleCompetitorPosition(competitor, fix);
} else {
@@ -22,7 +22,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceDefinition;
@@ -334,10 +333,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
eventSubscriber.subscribeCompetitors(new ICompetitorsListener() {
@Override
public void updateCompetitor(ICompetitor competitor) {
final Competitor domainCompetitor = TracTracRaceTrackerImpl.this.domainFactory.getOrCreateCompetitor(competitor);
logger.info("Competitor "+competitor+" was updated on TracTrac side. Maybe consider updating in competitor store as well. "+
"TracTrac competitor maps to "+domainCompetitor.getName()+" with sail ID "+domainCompetitor.getBoat().getSailID()+
" and boat class "+domainCompetitor.getBoat().getBoatClass().getName());
// TODO: How should we handle an updated sailID now as the sailID belongs to the boat in our domain model
TracTracRaceTrackerImpl.this.domainFactory.getOrCreateCompetitorAndBoat(competitor);
}
@Override
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.ScoringSchemeType;
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.RaceDTO;
@@ -56,8 +57,15 @@ public interface DomainFactory extends SharedDomainFactory {
ScoringScheme createScoringScheme(ScoringSchemeType scoringSchemeType);
CompetitorDTO convertToCompetitorDTO(CompetitorWithBoat c);
/** Temporary functions -> 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<CompetitorDTO> getCompetitorDTOList(List<Competitor> competitors);
List<CompetitorDTO> getCompetitorDTOList(List<CompetitorWithBoat> competitors);
/** Temporary function -> REMOVE later on */
List<CompetitorWithoutBoatDTO> getCompetitorWithoutBoatDTOListTemp(List<Competitor> competitors);
List<CompetitorDTO> getCompetitorDTOListTemp(List<Competitor> competitors);
TrackedRaceDTO createTrackedRaceDTO(TrackedRace trackedRace);
@@ -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<Competitor> viaRaceLog = new RegisteredCompetitorsAnalyzer(getRaceLog(fleet), getRegattaLog()).analyze();
result = viaRaceLog;
result = new RegisteredCompetitorsAndBoatsAnalyzer(getRaceLog(fleet), getRegattaLog()).analyze();
}
return result;
}
@@ -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<Competitor, GPSFixMoving> 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<CompetitorDTO> getCompetitorDTOList(List<Competitor> competitors) {
public List<CompetitorDTO> getCompetitorDTOList(List<CompetitorWithBoat> competitors) {
List<CompetitorDTO> result = new ArrayList<CompetitorDTO>();
for (CompetitorWithBoat competitor : competitors) {
result.add(convertToCompetitorDTO(competitor));
}
return result;
}
@Override
public List<CompetitorDTO> getCompetitorDTOListTemp(List<Competitor> competitors) {
List<CompetitorDTO> result = new ArrayList<CompetitorDTO>();
for (Competitor competitor : competitors) {
result.add(convertToCompetitorDTO(competitor));
}
return result;
}
@Override
public List<CompetitorWithoutBoatDTO> getCompetitorWithoutBoatDTOListTemp(List<Competitor> competitors) {
List<CompetitorWithoutBoatDTO> result = new ArrayList<CompetitorWithoutBoatDTO>();
for (Competitor competitor : competitors) {
result.add(convertToCompetitorWithoutBoatDTO(competitor));
}
return result;
}
}
@@ -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);
@@ -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);
@@ -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<CompetitorWithoutBoatDTO> getCompetitorWithoutBoatDTOList(List<Competitor> competitors);
// List<CompetitorDTO> getCompetitorDTOList(List<CompetitorWithBoat> competitors);
Future<List<CompetitorDTO>> 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<Boat> allBoats = new HashSet<>();
for (final RaceColumn raceColumn : getRaceColumns()) {
Map<Competitor, Boat> 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();
@@ -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
@@ -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<Competitor, Boat> 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<Competitor, Boat> 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();
}
}
@@ -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 <C extends Competitor> 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
@@ -31,8 +31,7 @@ public class GetCompetitorSuggestionAction implements SailingAction<CompetitorSu
private final AbstractListFilter<Competitor> competitorFilter = new AbstractListFilter<Competitor>() {
@Override
public Iterable<String> 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());
}
};
@@ -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;
@@ -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<RaceLogEvent>, 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;
@@ -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
@@ -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);
@@ -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 <code>true</code> then only the name and UUID is returned
*/
private Element createCompetitorXML(Competitor competitor, Leaderboard leaderboard, boolean shortVersion, Util.Pair<Double, Vector<String>> competitorConfidenceAndErrorMessages) throws NoWindException, IOException, ServletException {
private Element createCompetitorXML(Competitor competitor, Boat boatOfCompetitor, Leaderboard leaderboard,
boolean shortVersion, Util.Pair<Double, Vector<String>> 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<Element> racesElements = new ArrayList<Element>();
final List<Element> competitorElements = new ArrayList<Element>();
for (Competitor competitor : leaderboard.getAllCompetitors()) {
Boat boatOfCompetitor = leaderboard.getBoatOfCompetitor(competitor);
Boat boatOfCompetitor = null; // TODO: Where can we get the boat here?
Util.Pair<Double, Vector<String>> competitorConfidenceAndErrorMessages = checkData(competitor, boatOfCompetitor);
competitorElements.add(createCompetitorXML(competitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages));
competitorElements.add(createCompetitorXML(competitor, boatOfCompetitor, leaderboard, /*shortVersion*/ false, competitorConfidenceAndErrorMessages));
}
List<Element> windData = new ArrayList<Element>();
TrackedRace raceBefore = null; int sameDayGroupIndex = 0; int raceCounter = 0;
@@ -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<DataLoaderResult<Collection<Competitor>>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, "Creating Competitor-OnlineDataLoader " + id);
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorWithBoatJsonDeserializer(domainFactory.getCompetitorStore(),
new TeamJsonDeserializer(new PersonJsonDeserializer(new NationalityJsonDeserializer(domainFactory))),
new BoatJsonDeserializer(domainFactory, new BoatClassJsonDeserializer(domainFactory)));
JsonDeserializer<Competitor> competitorDeserializer = new CompetitorJsonDeserializer(domainFactory.getCompetitorStore(),
new TeamJsonDeserializer(new PersonJsonDeserializer(new NationalityJsonDeserializer(domainFactory))));
DataParser<Collection<Competitor>> parser = new CompetitorsDataParser(competitorDeserializer);
DataHandler<Collection<Competitor>> handler = new CompetitorsDataHandler(OnlineDataManager.this, managedRace);
@@ -39,8 +39,11 @@ public class CompetitorAdapter extends RecyclerView.Adapter<CompetitorAdapter.Vi
if (competitor != null) {
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();
if (holder.competitor != null) {
@@ -2,7 +2,9 @@ package com.sap.sailing.racecommittee.app.ui.comparators;
import java.util.Comparator;
import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorWithBoat;
import com.sap.sse.common.util.NaturalComparator;
public class CompetitorSailIdComparator implements Comparator<Competitor> {
@@ -14,17 +16,24 @@ public class CompetitorSailIdComparator implements Comparator<Competitor> {
}
@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;
}
}
@@ -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,