Merge remote-tracking branch 'origin/master' into mark-rounding-inference

This commit is contained in:
Nicolas committed 2014-06-02 16:03:18 +02:00
commit e14f43017b
42 files changed
+449 -213

No files matched your search

@@ -79,4 +79,6 @@ public interface EventBase extends Named, Renamable, WithID {
* <code>null</code>)
*/
void setVideoURLs(Iterable<URL> videoURLs);
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
}
@@ -0,0 +1,10 @@
package com.sap.sailing.domain.base;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sailing.domain.common.WithID;
public interface LeaderboardGroupBase extends Renamable, WithID {
String getDescription();
void setDescriptiom(String description);
boolean hasOverallLeaderboard();
}
@@ -12,7 +12,7 @@ import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.Util;
public class EventBaseImpl implements EventBase {
public abstract class EventBaseImpl implements EventBase {
private static final long serialVersionUID = -5749964088848611074L;
private String name;
@@ -24,14 +24,14 @@ public class EventBaseImpl implements EventBase {
private ConcurrentLinkedQueue<URL> imageURLs;
private ConcurrentLinkedQueue<URL> videoURLs;
public EventBaseImpl(String name, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, UUID id) {
protected EventBaseImpl(String name, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, UUID id) {
this(name, startDate, endDate, new VenueImpl(venueName), isPublic, id);
}
/**
* @param venue must not be <code>null</code>
*/
public EventBaseImpl(String name, TimePoint startDate, TimePoint endDate, Venue venue, boolean isPublic, UUID id) {
protected EventBaseImpl(String name, TimePoint startDate, TimePoint endDate, Venue venue, boolean isPublic, UUID id) {
assert venue != null;
this.id = id;
this.name = name;
@@ -0,0 +1,54 @@
package com.sap.sailing.domain.base.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.UUID;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
public abstract class LeaderboardGroupBaseImpl implements LeaderboardGroupBase {
private static final long serialVersionUID = 5769435569603360651L;
private UUID id;
private String name;
private String description;
public LeaderboardGroupBaseImpl(UUID id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
if (id == null) {
id = UUID.randomUUID();
}
}
@Override
public UUID getId() {
return id;
}
@Override
public String getDescription() {
return description;
}
@Override
public void setDescriptiom(String description) {
this.description = description;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
@@ -0,0 +1,37 @@
package com.sap.sailing.domain.base.impl;
import java.util.UUID;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.common.TimePoint;
/**
* A simplified implementation of the {@link EventBase} interface which maintains an immutable collection of
* {@link LeaderboardGroupBase} objects to implement the {@link #getLeaderboardGroups()} method.
*
* @author Axel Uhl (D043530)
*
*/
public class StrippedEventImpl extends EventBaseImpl {
private static final long serialVersionUID = 5608501747499933988L;
private final Iterable<LeaderboardGroupBase> leaderboardGroups;
public StrippedEventImpl(String name, TimePoint startDate, TimePoint endDate, String venueName,
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups) {
super(name, startDate, endDate, venueName, isPublic, id);
this.leaderboardGroups = leaderboardGroups;
}
public StrippedEventImpl(String name, TimePoint startDate, TimePoint endDate, Venue venue,
boolean isPublic, UUID id, Iterable<LeaderboardGroupBase> leaderboardGroups) {
super(name, startDate, endDate, venue, isPublic, id);
this.leaderboardGroups = leaderboardGroups;
}
@Override
public Iterable<LeaderboardGroupBase> getLeaderboardGroups() {
return leaderboardGroups;
}
}
@@ -0,0 +1,18 @@
package com.sap.sailing.domain.base.impl;
import java.util.UUID;
public class StrippedLeaderboardGroupImpl extends LeaderboardGroupBaseImpl {
private static final long serialVersionUID = 7263952130620919924L;
private final boolean hasOverallLeaderboard;
public StrippedLeaderboardGroupImpl(UUID id, String name, String description, boolean hasOverallLeaderboard) {
super(id, name, description);
this.hasOverallLeaderboard = hasOverallLeaderboard;
}
@Override
public boolean hasOverallLeaderboard() {
return hasOverallLeaderboard;
}
}
@@ -2,9 +2,6 @@ package com.sap.sailing.domain.base;
import java.util.UUID;
import com.sap.sailing.domain.common.Named;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
/**
@@ -15,7 +12,7 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
* @author Axel Uhl (D043530)
*
*/
public interface Event extends Named, Renamable, WithID, EventBase {
public interface Event extends EventBase {
Iterable<Regatta> getRegattas();
void addRegatta(Regatta regatta);
@@ -33,6 +30,7 @@ public interface Event extends Named, Renamable, WithID, EventBase {
* change the iteration order, {@link #removeLeaderboardGroup(LeaderboardGroup)} and
* {@link #addLeaderboardGroup(LeaderboardGroup)} need to be used.
*/
@Override
Iterable<LeaderboardGroup> getLeaderboardGroups();
void addLeaderboardGroup(LeaderboardGroup leaderboardGroup);
@@ -3,7 +3,7 @@ package com.sap.sailing.domain.leaderboard;
import java.util.Collection;
import java.util.UUID;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.common.WithID;
/**
@@ -24,15 +24,10 @@ import com.sap.sailing.domain.common.WithID;
*
* @author Frank Mittag (c5163874)
*/
public interface LeaderboardGroup extends Renamable {
public interface LeaderboardGroup extends LeaderboardGroupBase {
void addLeaderboardGroupListener(LeaderboardGroupListener listener);
void removeLeaderboardGroupListener(LeaderboardGroupListener listener);
String getDescription();
void setDescriptiom(String description);
boolean isDisplayGroupsInReverseOrder();
Iterable<Leaderboard> getLeaderboards();
int getIndexOf(Leaderboard leaderboard);
void addLeaderboard(Leaderboard leaderboard);
@@ -1,7 +1,5 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -9,17 +7,14 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
import com.sap.sailing.domain.common.WithID;
import com.sap.sailing.domain.base.impl.LeaderboardGroupBaseImpl;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.LeaderboardGroupListener;
public class LeaderboardGroupImpl implements WithID, LeaderboardGroup {
public class LeaderboardGroupImpl extends LeaderboardGroupBaseImpl implements LeaderboardGroup {
private static final long serialVersionUID = 2035927369446736934L;
private UUID id;
private String name;
private String description;
private boolean displayGroupsInReverseOrder;
private final List<Leaderboard> leaderboards;
private final Set<LeaderboardGroupListener> listeners;
@@ -42,26 +37,12 @@ public class LeaderboardGroupImpl implements WithID, LeaderboardGroup {
* Use this constructor when loading or deserializing a leaderboard group and the ID is known and is provided to the constructor.
*/
public LeaderboardGroupImpl(UUID id, String name, String description, boolean displayGroupsInReverseOrder, List<? extends Leaderboard> leaderboards) {
this.id = id;
this.name = name;
this.description = description;
super(id, name, description);
this.displayGroupsInReverseOrder = displayGroupsInReverseOrder;
this.leaderboards = new ArrayList<Leaderboard>(leaderboards);
this.listeners = new HashSet<LeaderboardGroupListener>();
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
if (id == null) {
id = UUID.randomUUID();
}
}
@Override
public UUID getId() {
return id;
}
@Override
public void addLeaderboardGroupListener(LeaderboardGroupListener listener) {
synchronized (listeners) {
@@ -94,34 +75,21 @@ public class LeaderboardGroupImpl implements WithID, LeaderboardGroup {
}
}
@Override
public Leaderboard getOverallLeaderboard() {
return overallLeaderboard;
}
@Override
public boolean hasOverallLeaderboard() {
return getOverallLeaderboard() != null;
}
@Override
public void setOverallLeaderboard(Leaderboard overallLeaderboard) {
this.overallLeaderboard = overallLeaderboard;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public String getDescription() {
return description;
}
@Override
public void setDescriptiom(String description) {
this.description = description;
}
@Override
public synchronized Iterable<Leaderboard> getLeaderboards() {
return new ArrayList<Leaderboard>(leaderboards);
@@ -63,8 +63,8 @@ public class DynamicGPSFixMovingTrackImpl<ItemType> extends GPSFixTrackImpl<Item
int i=0;
GPSFixMoving last = relevantFixes.get(i);
// if speed is within reasonable bounds, add fix's own speed/bearing; this also works if only one
// "relevant" fix is found
if (maxSpeedForSmoothing == null || last.getSpeed().compareTo(maxSpeedForSmoothing) <= 0) {
// "relevant" fix is found; exclude SOG/COG of fixes with SOG/COG==0/0
if ((last.getSpeed().getBearing().getDegrees() != 0 || last.getSpeed().getKnots() > 0) && (maxSpeedForSmoothing == null || last.getSpeed().compareTo(maxSpeedForSmoothing) <= 0)) {
SpeedWithConfidenceImpl<TimePoint> speedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(
last.getSpeed(),
/* original confidence */0.9, last.getTimePoint());
@@ -78,8 +78,9 @@ public class DynamicGPSFixMovingTrackImpl<ItemType> extends GPSFixTrackImpl<Item
aggregateSpeedAndBearingFromLastToNext(speeds, bearingCluster, last, next);
// add to average the speed and bearing provided by the GPSFixMoving
// if speed is within reasonable bounds, add fix's own speed/bearing; this also works if only one
// "relevant" fix is found
if (maxSpeedForSmoothing == null || next.getSpeed().compareTo(maxSpeedForSmoothing) <= 0) {
// "relevant" fix is found; exclude announced SOG/COG if 0/0
if ((last.getSpeed().getBearing().getDegrees() != 0 || last.getSpeed().getKnots() > 0)
&& (maxSpeedForSmoothing == null || next.getSpeed().compareTo(maxSpeedForSmoothing) <= 0)) {
SpeedWithConfidenceImpl<TimePoint> computedSpeedWithConfidence = new SpeedWithConfidenceImpl<TimePoint>(
next.getSpeed(), /* original confidence */0.9, next.getTimePoint());
speeds.add(computedSpeedWithConfidence);
@@ -7,7 +7,7 @@
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/AdminConsole.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.gwt.ui"/>
</listAttribute>
@@ -53,7 +53,7 @@
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/UserManagement.html com.sap.sailing.gwt.ui.UserManagement -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/TvView.html com.sap.sailing.gwt.ui.TvView -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9997 -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/UserManagement.html com.sap.sailing.gwt.ui.UserManagement -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/TvView.html com.sap.sailing.gwt.ui.TvView -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.VideoPopup"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -XX:MaxPermSize=512m"/>
</launchConfiguration>
@@ -25,8 +25,9 @@ public abstract class DetailTypeColumn<FieldType extends Comparable<?>, Renderin
T get(LeaderboardRowDTO row);
}
protected DetailTypeColumn(DetailType detailType, LegDetailField<FieldType> field, Cell<RenderingType> cell, String headerStyle, String columnStyle) {
super(cell, detailType.getDefaultSortingOrder());
protected DetailTypeColumn(DetailType detailType, LegDetailField<FieldType> field, Cell<RenderingType> cell,
String headerStyle, String columnStyle, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(cell, detailType.getDefaultSortingOrder(), displayedLeaderboardRowsProvider);
setHorizontalAlignment(ALIGN_CENTER);
this.title = DetailTypeFormatter.format(detailType);
this.unit = DetailTypeFormatter.getUnit(detailType).isEmpty() ? "" : "[" + DetailTypeFormatter.getUnit(detailType) + "]";
@@ -0,0 +1,24 @@
package com.sap.sailing.gwt.ui.leaderboard;
import java.util.Collection;
import com.sap.sailing.domain.common.dto.AbstractLeaderboardDTO;
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
/**
* A {@link LeaderboardPanel} does not always display all rows available. One reason for filtering can be a filter set
* explicitly by the user. Another can be that the leaderboard panel is configured to only show entries for one
* particular race. Other UI controls that need to know which rows are being shown shall not need to see the entire
* {@link LeaderboardPanel} interface. Therefore, this interface provides the capabilities needed.
*
* @author Axel Uhl (D043530)
*
*/
public interface DisplayedLeaderboardRowsProvider {
/**
* Extracts the rows to display of the <code>leaderboard</code>. These are all {@link AbstractLeaderboardDTO#rows
* rows} in case {@link #preSelectedRace} is <code>null</code>, or only the rows of the competitors who scored in
* the race identified by {@link #preSelectedRace} otherwise.
*/
public Collection<LeaderboardRowDTO> getRowsToDisplay();
}
@@ -48,8 +48,8 @@ public abstract class ExpandableSortableColumn<C> extends SortableColumn<Leaderb
public ExpandableSortableColumn(LeaderboardPanel leaderboardPanel, boolean enableExpansion, Cell<C> cell,
SortingOrder preferredSortingOrder, StringMessages stringConstants, String detailHeaderStyle, String detailColumnStyle,
List<DetailType> detailSelection) {
super(cell, preferredSortingOrder);
List<DetailType> detailSelection, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(cell, preferredSortingOrder, displayedLeaderboardRowsProvider);
this.enableExpansion = enableExpansion;
this.leaderboardPanel = leaderboardPanel;
this.detailSelection = detailSelection;
@@ -171,7 +171,7 @@ public abstract class ExpandableSortableColumn<C> extends SortableColumn<Leaderb
if (insertIndex != -1) {
insertIndex++;
for (SortableColumn<LeaderboardRowDTO, ?> column : getAllVisibleChildren()) {
column.updateMinMax(getLeaderboardPanel().getLeaderboard());
column.updateMinMax();
getLeaderboardPanel().insertColumn(insertIndex++, column);
}
getLeaderboardPanel().getLeaderboardTable().redraw();
@@ -5,7 +5,6 @@ import com.google.gwt.cell.client.TextCell;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
import com.sap.sailing.gwt.ui.client.DetailTypeFormatter;
import com.sap.sailing.gwt.ui.client.NumberFormatterFactory;
@@ -17,9 +16,11 @@ public class FormattedDoubleDetailTypeColumn extends DetailTypeColumn<Double, St
/**
* Creates a new column for the given {@link DetailType}. Have a look at
* {@link DetailTypeFormatter#getUnit(DetailType)}, to see if the given type is supported.
* @param displayedLeaderboardRowsProvider TODO
*/
public FormattedDoubleDetailTypeColumn(DetailType detailType, LegDetailField<Double> field, String headerStyle, String columnStyle) {
super(detailType, field, new TextCell(), headerStyle, columnStyle);
public FormattedDoubleDetailTypeColumn(DetailType detailType, LegDetailField<Double> field, String headerStyle,
String columnStyle, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(detailType, field, new TextCell(), headerStyle, columnStyle, displayedLeaderboardRowsProvider);
formatter = createNumberFormatter(detailType);
this.minMaxRenderer = createMinMaxRenderer();
}
@@ -37,8 +38,8 @@ public class FormattedDoubleDetailTypeColumn extends DetailTypeColumn<Double, St
}
@Override
protected void updateMinMax(LeaderboardDTO leaderboard) {
getMinMaxRenderer().updateMinMax(leaderboard.rows.values());
protected void updateMinMax() {
getMinMaxRenderer().updateMinMax(getDisplayedLeaderboardRowsProvider());
}
protected NumberFormat getFormatter() {
@@ -102,7 +102,7 @@ import com.sap.sse.gwt.client.useragent.UserAgentDetails;
* @author Axel Uhl (D043530)
*
*/
public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayStateListener,
public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayStateListener, DisplayedLeaderboardRowsProvider,
Component<LeaderboardSettings>, IsEmbeddableComponent, CompetitorSelectionChangeListener, LeaderboardFetcher {
public static final String LOAD_LEADERBOARD_DATA_CATEGORY = "loadLeaderboardData";
private static final int RANK_COLUMN_INDEX = 0;
@@ -521,12 +521,12 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private final CompetitorColumnBase<LeaderboardRowDTO> base;
protected CompetitorColumn(CompetitorColumnBase<LeaderboardRowDTO> base) {
super(base.getCell(getLeaderboard()), SortingOrder.ASCENDING);
super(base.getCell(getLeaderboard()), SortingOrder.ASCENDING, LeaderboardPanel.this);
this.base = base;
}
public CompetitorColumn(CompositeCell<LeaderboardRowDTO> compositeCell, CompetitorColumnBase<LeaderboardRowDTO> base) {
super(compositeCell, SortingOrder.ASCENDING);
super(compositeCell, SortingOrder.ASCENDING, LeaderboardPanel.this);
this.base = base;
}
@@ -578,7 +578,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private final CompetitorFetcher<T> competitorFetcher;
protected SailIDColumn(CompetitorFetcher<T> competitorFetcher) {
super(new TextCell(), SortingOrder.ASCENDING);
super(new TextCell(), SortingOrder.ASCENDING, LeaderboardPanel.this);
this.competitorFetcher = competitorFetcher;
}
@@ -638,7 +638,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
public RaceColumn(RaceColumnDTO race, boolean enableExpansion, Cell<C> cell,
SortingOrder preferredSortingOrder, String headerStyle, String columnStyle) {
super(LeaderboardPanel.this, enableExpansion, cell, preferredSortingOrder, stringMessages,
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, selectedRaceDetails);
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, selectedRaceDetails, LeaderboardPanel.this);
setHorizontalAlignment(ALIGN_CENTER);
this.race = race;
this.headerStyle = headerStyle;
@@ -840,50 +840,50 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
Map<DetailType, SortableColumn<LeaderboardRowDTO, ?>> result = new HashMap<DetailType, SortableColumn<LeaderboardRowDTO, ?>>();
result.put(DetailType.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL,
new TimeSinceLastGpsFixColumn(DetailType.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL,
new RaceRatioBetweenTimeSinceLastPositionFixAndAverageSamplingInterval(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
new RaceRatioBetweenTimeSinceLastPositionFixAndAverageSamplingInterval(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_DISTANCE_TRAVELED,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TRAVELED, new RaceDistanceTraveledInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new RaceAverageSpeedInKnots(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_GAP_TO_LEADER_IN_SECONDS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_GAP_TO_LEADER_IN_SECONDS, new RaceGapToLeaderInSeconds(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, new CurrentSpeedOverGroundInKnots(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS, new RaceDistanceToLeaderInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS, new RaceAverageAbsoluteCrossTrackErrorInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS, new RaceAverageSignedCrossTrackErrorInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START, new DistanceToStartFiveSecondsBeforeStartInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START, new SpeedFiveSecondsBeforeStartInKnots(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.DISTANCE_TO_START_AT_RACE_START,
new FormattedDoubleDetailTypeColumn(DetailType.DISTANCE_TO_START_AT_RACE_START, new DistanceToStartAtRaceStartInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.SPEED_OVER_GROUND_AT_RACE_START,
new FormattedDoubleDetailTypeColumn(DetailType.SPEED_OVER_GROUND_AT_RACE_START, new SpeedOverGroundAtRaceStartInKnots(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.SPEED_OVER_GROUND_WHEN_PASSING_START,
new FormattedDoubleDetailTypeColumn(DetailType.SPEED_OVER_GROUND_WHEN_PASSING_START, new SpeedOverGroundWhenPassingStartInKnots(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_PASSING_START_IN_METERS, new DistanceToStarboardSideOfStartLineInMeters(),
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.START_TACK, new StartingTackColumn(new TackWhenStarting(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
result.put(DetailType.NUMBER_OF_MANEUVERS, getManeuverCountRaceColumn());
result.put(DetailType.CURRENT_LEG,
new FormattedDoubleDetailTypeColumn(DetailType.CURRENT_LEG, new CurrentLeg(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
new FormattedDoubleDetailTypeColumn(DetailType.CURRENT_LEG, new CurrentLeg(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this));
result.put(DetailType.RACE_TIME_TRAVELED, getTimeTraveledRaceColumn());
return result;
@@ -897,7 +897,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private ManeuverCountRaceColumn getManeuverCountRaceColumn() {
return new ManeuverCountRaceColumn(getLeaderboardPanel(), this, stringMessages,
LeaderboardPanel.this.selectedManeuverDetails, LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE,
LEG_DETAIL_COLUMN_HEADER_STYLE, LEG_DETAIL_COLUMN_STYLE);
LEG_DETAIL_COLUMN_HEADER_STYLE, LEG_DETAIL_COLUMN_STYLE, LeaderboardPanel.this);
}
@Override
@@ -1273,7 +1273,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private final String columnStyle;
protected TotalsColumn(String columnStyle) {
super(new TextCell(), SortingOrder.ASCENDING);
super(new TextCell(), SortingOrder.ASCENDING, LeaderboardPanel.this);
this.columnStyle = columnStyle;
setHorizontalAlignment(ALIGN_CENTER);
}
@@ -1317,12 +1317,12 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
protected class CarryColumn extends SortableColumn<LeaderboardRowDTO, String> {
public CarryColumn() {
super(new TextCell(), SortingOrder.ASCENDING);
super(new TextCell(), SortingOrder.ASCENDING, LeaderboardPanel.this);
setSortable(true);
}
protected CarryColumn(EditTextCell editTextCell) {
super(editTextCell, SortingOrder.ASCENDING);
super(editTextCell, SortingOrder.ASCENDING, LeaderboardPanel.this);
setSortable(true);
}
@@ -1357,7 +1357,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private class TotalRankColumn extends SortableColumn<LeaderboardRowDTO, String> {
public TotalRankColumn() {
super(new TextCell(), SortingOrder.ASCENDING);
super(new TextCell(), SortingOrder.ASCENDING, LeaderboardPanel.this);
setHorizontalAlignment(ALIGN_CENTER);
setSortable(true);
}
@@ -1388,7 +1388,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
private class StartingTackColumn extends DetailTypeColumn<Tack, String> {
public StartingTackColumn(LegDetailField<Tack> field, String headerStyle, String columnStyle) {
super(DetailType.START_TACK, field, new TextCell(), headerStyle, columnStyle);
super(DetailType.START_TACK, field, new TextCell(), headerStyle, columnStyle, LeaderboardPanel.this);
}
@Override
@@ -1604,14 +1604,14 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
Map<DetailType, SortableColumn<LeaderboardRowDTO, ?>> result = new HashMap<DetailType, SortableColumn<LeaderboardRowDTO, ?>>();
result.put(DetailType.TOTAL_DISTANCE_TRAVELED,
new FormattedDoubleDetailTypeColumn(DetailType.TOTAL_DISTANCE_TRAVELED,
new TotalDistanceTraveledInMetersField(), RACE_COLUMN_HEADER_STYLE, RACE_COLUMN_STYLE));
new TotalDistanceTraveledInMetersField(), RACE_COLUMN_HEADER_STYLE, RACE_COLUMN_STYLE, this));
result.put(DetailType.TOTAL_AVERAGE_SPEED_OVER_GROUND,
new FormattedDoubleDetailTypeColumn(DetailType.TOTAL_AVERAGE_SPEED_OVER_GROUND,
new TotalAverageSpeedOverGroundField(), RACE_COLUMN_HEADER_STYLE, RACE_COLUMN_STYLE));
new TotalAverageSpeedOverGroundField(), RACE_COLUMN_HEADER_STYLE, RACE_COLUMN_STYLE, this));
result.put(DetailType.MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS, new MaxSpeedOverallColumn(RACE_COLUMN_HEADER_STYLE,
RACE_COLUMN_STYLE));
RACE_COLUMN_STYLE, this));
result.put(DetailType.TOTAL_TIME_SAILED_IN_SECONDS, createOverallTimeTraveledColumn());
return result;
@@ -1888,7 +1888,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
}
adjustDelayToLive();
getData().getList().clear();
getData().getList().addAll(getRowsToDisplay(leaderboard));
getData().getList().addAll(getRowsToDisplay());
RaceColumn<?> lastRaceColumn = null;
for (int i=getLeaderboardTable().getColumnCount()-1; i>=0; i--) {
if (getLeaderboardTable().getColumn(i) instanceof RaceColumn<?>) {
@@ -1898,7 +1898,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
}
for (int i = 0; i < getLeaderboardTable().getColumnCount(); i++) {
SortableColumn<?, ?> c = (SortableColumn<?, ?>) getLeaderboardTable().getColumn(i);
c.updateMinMax(leaderboard);
c.updateMinMax();
// Toggle pre-selected race, if the setting is set and it isn't open yet, or the last race column if that was requested
if ((!autoExpandPerformedOnce && isAutoExpandPreSelectedRace() && c instanceof RaceColumn<?>
&& ((RaceColumn<?>) c).getRace().hasTrackedRace(preSelectedRace)) ||
@@ -2025,19 +2025,20 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
* rows} in case {@link #preSelectedRace} is <code>null</code>, or only the rows of the competitors who scored in
* the race identified by {@link #preSelectedRace} otherwise.
*/
private Collection<LeaderboardRowDTO> getRowsToDisplay(LeaderboardDTO leaderboard) {
@Override
public Collection<LeaderboardRowDTO> getRowsToDisplay() {
Collection<LeaderboardRowDTO> result;
Iterable<CompetitorDTO> allFilteredCompetitors = competitorSelectionProvider.getFilteredCompetitors();
result = new ArrayList<LeaderboardRowDTO>();
if (preSelectedRace == null) {
for (CompetitorDTO competitor : leaderboard.rows.keySet()) {
if(Util.contains(allFilteredCompetitors, competitor)) {
if (Util.contains(allFilteredCompetitors, competitor)) {
result.add(leaderboard.rows.get(competitor));
}
}
} else {
for (CompetitorDTO competitorInPreSelectedRace : getCompetitors(preSelectedRace)) {
if(Util.contains(allFilteredCompetitors, competitorInPreSelectedRace)) {
if (Util.contains(allFilteredCompetitors, competitorInPreSelectedRace)) {
result.add(leaderboard.rows.get(competitorInPreSelectedRace));
}
}
@@ -146,7 +146,7 @@ public class LegColumn extends ExpandableSortableColumn<String> {
private class ManeuverCountLegDetailsColumn extends FormattedDoubleDetailTypeColumn {
public ManeuverCountLegDetailsColumn(String headerStyle, String columnStyle) {
super(DetailType.NUMBER_OF_MANEUVERS, null, headerStyle, columnStyle);
super(DetailType.NUMBER_OF_MANEUVERS, null, headerStyle, columnStyle, getLeaderboardPanel());
}
@Override
@@ -222,7 +222,7 @@ public class LegColumn extends ExpandableSortableColumn<String> {
List<DetailType> legDetailSelection, String headerStyle, String columnStyle,
String detailHeaderStyle, String detailColumnStyle) {
super(leaderboardPanel, /* expandable */true /* all legs have details */, new TextCell(), preferredSortingOrder,
stringMessages, detailHeaderStyle, detailColumnStyle, legDetailSelection);
stringMessages, detailHeaderStyle, detailColumnStyle, legDetailSelection, leaderboardPanel);
setHorizontalAlignment(ALIGN_CENTER);
this.raceName = raceName;
this.legIndex = legIndex;
@@ -248,47 +248,47 @@ public class LegColumn extends ExpandableSortableColumn<String> {
Map<DetailType, SortableColumn<LeaderboardRowDTO, ?>> result = new HashMap<DetailType, SortableColumn<LeaderboardRowDTO, ?>>();
result.put(DetailType.DISTANCE_TRAVELED,
new FormattedDoubleDetailTypeColumn(DetailType.DISTANCE_TRAVELED, new DistanceTraveledInMeters(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.DISTANCE_TRAVELED, new DistanceTraveledInMeters(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new AverageSpeedOverGroundInKnots(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new AverageSpeedOverGroundInKnots(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS,
new FormattedDoubleDetailTypeColumn(DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS, new CurrentSpeedOverGroundInKnots(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS, new CurrentSpeedOverGroundInKnots(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS,
new FormattedDoubleDetailTypeColumn(DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS, new EstimatedTimeToNextWaypointInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.GAP_TO_LEADER_IN_SECONDS,
new FormattedDoubleDetailTypeColumn(DetailType.GAP_TO_LEADER_IN_SECONDS, new GapToLeaderInSeconds(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.GAP_TO_LEADER_IN_SECONDS, new GapToLeaderInSeconds(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.GAP_CHANGE_SINCE_LEG_START_IN_SECONDS,
new FormattedDoubleDetailTypeColumn(DetailType.GAP_CHANGE_SINCE_LEG_START_IN_SECONDS, new GapChangeSinceLegStartInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED,
new SideToWhichMarkAtLegStartWasRoundedColumn(stringMessages.sideToWhichMarkAtLegStartWasRounded(),
new SideToWhichMarkAtLegStartWasRounded(), detailHeaderStyle, detailColumnStyle, stringMessages));
new SideToWhichMarkAtLegStartWasRounded(), detailHeaderStyle, detailColumnStyle, stringMessages, leaderboardPanel));
result.put(DetailType.VELOCITY_MADE_GOOD_IN_KNOTS,
new FormattedDoubleDetailTypeColumn(DetailType.VELOCITY_MADE_GOOD_IN_KNOTS, new VelocityMadeGoodInKnots(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.VELOCITY_MADE_GOOD_IN_KNOTS, new VelocityMadeGoodInKnots(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS, new WindwardDistanceToGoInMeters(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS, new WindwardDistanceToGoInMeters(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.RANK_GAIN, new RankGainColumn(stringMessages.rankGain(), new RankGain(), detailHeaderStyle, detailColumnStyle));
result.put(DetailType.RANK_GAIN, new RankGainColumn(stringMessages.rankGain(), new RankGain(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.NUMBER_OF_MANEUVERS, new ManeuverCountLegDetailsColumn(detailHeaderStyle, detailColumnStyle));
result.put(DetailType.TIME_TRAVELED,
new FormattedDoubleDetailTypeColumn(DetailType.TIME_TRAVELED, new TimeTraveledInSeconds(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.TIME_TRAVELED, new TimeTraveledInSeconds(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS, new AverageAbsoluteCrossTrackErrorInMeters(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS, new AverageAbsoluteCrossTrackErrorInMeters(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS, new AverageSignedCrossTrackErrorInMeters(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS, new AverageSignedCrossTrackErrorInMeters(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
return result;
}
@@ -12,7 +12,6 @@ import com.google.gwt.user.cellview.client.Header;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.ManeuverType;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO;
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
import com.sap.sailing.domain.common.dto.LegEntryDTO;
@@ -87,9 +86,9 @@ public class ManeuverCountRaceColumn extends ExpandableSortableColumn<String> im
public ManeuverCountRaceColumn(LeaderboardPanel leaderboardPanel, RaceNameProvider raceNameProvider,
StringMessages stringConstants, List<DetailType> maneuverDetailSelection, String headerStyle,
String columnStylee, String detailHeaderStyle, String detailColumnStyle) {
String columnStylee, String detailHeaderStyle, String detailColumnStyle, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(leaderboardPanel, /* expandable */true /* all legs have details */, new TextCell(), DetailType.NUMBER_OF_MANEUVERS.getDefaultSortingOrder(),
stringConstants, detailHeaderStyle, detailColumnStyle, maneuverDetailSelection);
stringConstants, detailHeaderStyle, detailColumnStyle, maneuverDetailSelection, displayedLeaderboardRowsProvider);
setHorizontalAlignment(ALIGN_CENTER);
this.stringMessages = stringConstants;
this.raceNameProvider = raceNameProvider;
@@ -229,8 +228,8 @@ public class ManeuverCountRaceColumn extends ExpandableSortableColumn<String> im
}
@Override
protected void updateMinMax(LeaderboardDTO leaderboard) {
minmaxRenderer.updateMinMax(leaderboard.rows.values());
protected void updateMinMax() {
minmaxRenderer.updateMinMax(getDisplayedLeaderboardRowsProvider());
}
@Override
@@ -238,24 +237,24 @@ public class ManeuverCountRaceColumn extends ExpandableSortableColumn<String> im
LeaderboardPanel leaderboardPanel, StringMessages stringMessages, String detailHeaderStyle,
String detailColumnStyle) {
Map<DetailType, SortableColumn<LeaderboardRowDTO, ?>> result = new HashMap<DetailType, SortableColumn<LeaderboardRowDTO, ?>>();
result.put(DetailType.TACK, new FormattedDoubleDetailTypeColumn(DetailType.TACK, new NumberOfTacks(), detailHeaderStyle, detailColumnStyle));
result.put(DetailType.TACK, new FormattedDoubleDetailTypeColumn(DetailType.TACK, new NumberOfTacks(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.JIBE, new FormattedDoubleDetailTypeColumn(DetailType.JIBE, new NumberOfJibes(), detailHeaderStyle, detailColumnStyle));
result.put(DetailType.JIBE, new FormattedDoubleDetailTypeColumn(DetailType.JIBE, new NumberOfJibes(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.PENALTY_CIRCLE,
new FormattedDoubleDetailTypeColumn(DetailType.PENALTY_CIRCLE, new NumberOfPenaltyCircles(), detailHeaderStyle, detailColumnStyle));
new FormattedDoubleDetailTypeColumn(DetailType.PENALTY_CIRCLE, new NumberOfPenaltyCircles(), detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.AVERAGE_TACK_LOSS_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_TACK_LOSS_IN_METERS, new AverageTackLossInMeters(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.AVERAGE_JIBE_LOSS_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_JIBE_LOSS_IN_METERS, new AverageJibeLossInMeters(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.AVERAGE_MANEUVER_LOSS_IN_METERS,
new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_MANEUVER_LOSS_IN_METERS, new AverageManeuverLossInMeters(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
return result;
}
@@ -20,8 +20,8 @@ public class MaxSpeedOverallColumn extends FormattedDoubleDetailTypeColumn {
}
}
public MaxSpeedOverallColumn(String headerStyle, String columnStyle) {
super(DetailType.MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS, new MaxSpeedOverallField(), headerStyle, columnStyle);
public MaxSpeedOverallColumn(String headerStyle, String columnStyle, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(DetailType.MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS, new MaxSpeedOverallField(), headerStyle, columnStyle, displayedLeaderboardRowsProvider);
}
/**
@@ -1,6 +1,5 @@
package com.sap.sailing.gwt.ui.leaderboard;
import java.util.Collection;
import java.util.Comparator;
import com.google.gwt.cell.client.Cell.Context;
@@ -51,7 +50,7 @@ public class MinMaxRenderer {
/**
* Gets the percentage of a {@link LeaderboardRowDTO}. If no minimum or maximum value was set by calling
* {@link MinMaxRenderer#updateMinMax(Collection)} before zero is returned.
* {@link MinMaxRenderer#updateMinMax(DisplayedLeaderboardRowsProvider)} before zero is returned.
*
* @param row
* The row to get the percentage for.
@@ -82,13 +81,13 @@ public class MinMaxRenderer {
/**
* Updates the {@link MinMaxRenderer#minimumValue} and {@link MinMaxRenderer#maximumValue}.
*
* @param values
* @param displayedLeaderboardRowsProvider
* The values of {@link LeaderboardRowDTO}s to determine the minimum and maximum values for.
*/
public void updateMinMax(Collection<LeaderboardRowDTO> values) {
public void updateMinMax(DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
LeaderboardRowDTO minimumRow = null;
LeaderboardRowDTO maximumRow = null;
for (LeaderboardRowDTO row : values) {
for (LeaderboardRowDTO row : displayedLeaderboardRowsProvider.getRowsToDisplay()) {
if (valueProvider.getDoubleValue(row) != null
&& (minimumRow == null || comparator.compare(minimumRow, row) > 0)) {
minimumRow = row;
@@ -12,7 +12,6 @@ import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.Header;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter;
import com.sap.sailing.gwt.ui.client.DetailTypeFormatter;
@@ -34,7 +33,7 @@ public class OverallTimeTraveledColumn extends ExpandableSortableColumn<String>
String detailColumnStyle) {
super(leaderboardPanel, /* expandable */true, new TextCell(), DETAIL_TYPE.getDefaultSortingOrder(),
stringMessages, detailHeaderStyle, detailColumnStyle,
Arrays.asList(DetailType.TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS, DetailType.TOTAL_TIME_SAILED_UPWIND_IN_SECONDS, DetailType.TOTAL_TIME_SAILED_REACHING_IN_SECONDS));
Arrays.asList(DetailType.TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS, DetailType.TOTAL_TIME_SAILED_UPWIND_IN_SECONDS, DetailType.TOTAL_TIME_SAILED_REACHING_IN_SECONDS), leaderboardPanel);
setHorizontalAlignment(ALIGN_CENTER);
this.stringMessages = stringMessages;
this.columnStyle = columnStyle;
@@ -55,13 +54,13 @@ public class OverallTimeTraveledColumn extends ExpandableSortableColumn<String>
result.put(DetailType.TOTAL_TIME_SAILED_UPWIND_IN_SECONDS,
new TotalTimeColumn(DetailType.TOTAL_TIME_SAILED_UPWIND_IN_SECONDS, new TotalTimeSailedUpwindInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS,
new TotalTimeColumn(DetailType.TOTAL_TIME_SAILED_DOWNWIND_IN_SECONDS, new TotalTimeSailedDownwindInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.TOTAL_TIME_SAILED_REACHING_IN_SECONDS,
new TotalTimeColumn(DetailType.TOTAL_TIME_SAILED_REACHING_IN_SECONDS, new TotalTimeSailedReachingInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
return result;
}
@@ -141,8 +140,8 @@ public class OverallTimeTraveledColumn extends ExpandableSortableColumn<String>
}
@Override
protected void updateMinMax(LeaderboardDTO leaderboard) {
minmaxRenderer.updateMinMax(leaderboard.rows.values());
protected void updateMinMax() {
minmaxRenderer.updateMinMax(getDisplayedLeaderboardRowsProvider());
}
/**
@@ -12,8 +12,9 @@ import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
public class RankGainColumn extends DetailTypeColumn<Integer, Integer> {
private static final LeaderboardResources leaderboardResources = GWT.create(LeaderboardResources.class);
public RankGainColumn(String title, LegDetailField<Integer> field, String headerStyle, String columnStyle) {
super(DetailType.RANK_GAIN, field, new RankGainCell(), headerStyle, columnStyle);
public RankGainColumn(String title, LegDetailField<Integer> field, String headerStyle, String columnStyle,
DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(DetailType.RANK_GAIN, field, new RankGainCell(), headerStyle, columnStyle, displayedLeaderboardRowsProvider);
}
@Override
@@ -9,8 +9,10 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
public class SideToWhichMarkAtLegStartWasRoundedColumn extends DetailTypeColumn<NauticalSide, String> {
private final StringMessages stringMessages;
public SideToWhichMarkAtLegStartWasRoundedColumn(String title, LegDetailField<NauticalSide> field, String headerStyle, String columnStyle, StringMessages stringMessages) {
super(DetailType.SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED, field, new TextCell(), headerStyle, columnStyle);
public SideToWhichMarkAtLegStartWasRoundedColumn(String title, LegDetailField<NauticalSide> field,
String headerStyle, String columnStyle, StringMessages stringMessages,
DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(DetailType.SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED, field, new TextCell(), headerStyle, columnStyle, displayedLeaderboardRowsProvider);
this.stringMessages = stringMessages;
}
@@ -5,18 +5,28 @@ import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.Header;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.SortingOrder;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
public abstract class SortableColumn<T, C> extends Column<T, C> {
private SortingOrder preferredSortingOrder;
private final DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider;
protected SortableColumn(Cell<C> cell, SortingOrder preferredSortingOrder) {
protected SortableColumn(Cell<C> cell, SortingOrder preferredSortingOrder,
DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(cell);
setSortable(true);
this.preferredSortingOrder = preferredSortingOrder;
this.displayedLeaderboardRowsProvider = displayedLeaderboardRowsProvider;
}
protected void updateMinMax(LeaderboardDTO leaderboard) {}
/**
* Based on the rows returned by the {@link DisplayedLeaderboardRowsProvider} instance passed to the
* constructor, updates the min/max values for this column.
*/
protected void updateMinMax() {}
protected DisplayedLeaderboardRowsProvider getDisplayedLeaderboardRowsProvider() {
return displayedLeaderboardRowsProvider;
}
public abstract InvertibleComparator<T> getComparator();
@@ -6,8 +6,8 @@ public class TimeSinceLastGpsFixColumn extends FormattedDoubleDetailTypeColumn {
public TimeSinceLastGpsFixColumn(DetailType detailType,
com.sap.sailing.gwt.ui.leaderboard.DetailTypeColumn.LegDetailField<Double> field, String headerStyle,
String columnStyle) {
super(detailType, field, headerStyle, columnStyle);
String columnStyle, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(detailType, field, headerStyle, columnStyle, displayedLeaderboardRowsProvider);
}
@Override
@@ -12,7 +12,6 @@ import com.google.gwt.user.cellview.client.Header;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO;
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
import com.sap.sailing.domain.common.dto.LegEntryDTO;
@@ -36,7 +35,7 @@ public class TimeTraveledRaceColumn extends ExpandableSortableColumn<String> imp
String detailHeaderStyle, String detailColumnStyle) {
super(leaderboardPanel, /* expandable */true, new TextCell(), DETAIL_TYPE.getDefaultSortingOrder(),
stringMessages, detailHeaderStyle, detailColumnStyle,
Arrays.asList(DetailType.RACE_TIME_TRAVELED_UPWIND, DetailType.RACE_TIME_TRAVELED_DOWNWIND, DetailType.RACE_TIME_TRAVELED_REACHING));
Arrays.asList(DetailType.RACE_TIME_TRAVELED_UPWIND, DetailType.RACE_TIME_TRAVELED_DOWNWIND, DetailType.RACE_TIME_TRAVELED_REACHING), leaderboardPanel);
setHorizontalAlignment(ALIGN_CENTER);
this.raceNameProvider = raceNameProvider;
this.stringMessages = stringMessages;
@@ -88,13 +87,13 @@ public class TimeTraveledRaceColumn extends ExpandableSortableColumn<String> imp
result.put(DetailType.RACE_TIME_TRAVELED_UPWIND,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_TIME_TRAVELED_UPWIND, new RaceTimeTraveledUpwindInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.RACE_TIME_TRAVELED_DOWNWIND,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_TIME_TRAVELED_DOWNWIND, new RaceTimeTraveledDownwindInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
result.put(DetailType.RACE_TIME_TRAVELED_REACHING,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_TIME_TRAVELED_REACHING, new RaceTimeTraveledReachingInSeconds(),
detailHeaderStyle, detailColumnStyle));
detailHeaderStyle, detailColumnStyle, leaderboardPanel));
return result;
}
@@ -172,8 +171,8 @@ public class TimeTraveledRaceColumn extends ExpandableSortableColumn<String> imp
}
@Override
protected void updateMinMax(LeaderboardDTO leaderboard) {
minmaxRenderer.updateMinMax(leaderboard.rows.values());
protected void updateMinMax() {
minmaxRenderer.updateMinMax(getDisplayedLeaderboardRowsProvider());
}
/**
@@ -7,8 +7,9 @@ import com.sap.sailing.gwt.ui.client.NumberFormatterFactory;
public class TotalTimeColumn extends FormattedDoubleDetailTypeColumn {
protected TotalTimeColumn(DetailType detailType, LegDetailField<Double> field, String headerStyle, String columnStyle) {
super(detailType, field, headerStyle, columnStyle);
protected TotalTimeColumn(DetailType detailType, LegDetailField<Double> field, String headerStyle,
String columnStyle, DisplayedLeaderboardRowsProvider displayedLeaderboardRowsProvider) {
super(detailType, field, headerStyle, columnStyle, displayedLeaderboardRowsProvider);
}
@Override
@@ -144,7 +144,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
*/
private class SuppressedSailIDColumn extends SortableColumn<CompetitorDTO, String> {
protected SuppressedSailIDColumn() {
super(new TextCell(), SortingOrder.ASCENDING);
super(new TextCell(), SortingOrder.ASCENDING, EditableLeaderboardPanel.this);
}
@Override
@@ -189,7 +189,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
private final CompetitorColumnBase<CompetitorDTO> base;
protected SuppressedCompetitorColumn(CompetitorColumnBase<CompetitorDTO> base) {
super(base.getCell(getLeaderboard()), SortingOrder.ASCENDING);
super(base.getCell(getLeaderboard()), SortingOrder.ASCENDING, EditableLeaderboardPanel.this);
this.base = base;
}
@@ -1462,7 +1462,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint());
Wind wind = trackedRace.getWind(fix.getPosition(),toTimePointExcluding);
WindDTO windDTO = wind == null ? null : createWindDTOFromAlreadyAveraged(wind, toTimePointExcluding);
GPSFixDTO fixDTO = createGPSFixDTO(fix, fix.getSpeed(), windDTO, tack, legType, /* extrapolate */
GPSFixDTO fixDTO = createGPSFixDTO(fix, track.getEstimatedSpeed(fix.getTimePoint()), windDTO, tack, legType, /* extrapolate */
false);
fixesForCompetitor.add(fixDTO);
if (fixIter.hasNext()) {
@@ -22,10 +22,12 @@ import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
public class EventDataJsonSerializerTest {
@@ -36,7 +38,7 @@ public class EventDataJsonSerializerTest {
protected final Venue expectedVenue = new VenueImpl("Expected Venue");
protected JsonSerializer<Venue> venueSerializer;
protected EventJsonSerializer serializer;
protected EventBaseJsonSerializer serializer;
protected EventBaseJsonDeserializer deserializer;
protected EventBase event;
@@ -53,8 +55,8 @@ public class EventDataJsonSerializerTest {
when(event.getImageURLs()).thenReturn(Collections.<URL>emptySet());
when(event.getVideoURLs()).thenReturn(Collections.<URL>emptySet());
// ... and the serializer itself.
serializer = new EventJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()));
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)));
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
}
@Test
@@ -63,16 +65,16 @@ public class EventDataJsonSerializerTest {
assertEquals(
expectedId,
UUID.fromString(result.get(EventJsonSerializer.FIELD_ID).toString()));
UUID.fromString(result.get(EventBaseJsonSerializer.FIELD_ID).toString()));
assertEquals(
expectedName,
result.get(EventJsonSerializer.FIELD_NAME));
result.get(EventBaseJsonSerializer.FIELD_NAME));
assertEquals(
expectedStartDate,
new MillisecondsTimePoint(((Number) result.get(EventJsonSerializer.FIELD_START_DATE)).longValue()));
new MillisecondsTimePoint(((Number) result.get(EventBaseJsonSerializer.FIELD_START_DATE)).longValue()));
assertEquals(
expectedEndDate,
new MillisecondsTimePoint(((Number) result.get(EventJsonSerializer.FIELD_END_DATE)).longValue()));
new MillisecondsTimePoint(((Number) result.get(EventBaseJsonSerializer.FIELD_END_DATE)).longValue()));
}
@Test
@@ -2,6 +2,7 @@ package com.sap.sailing.server.gateway.serialization.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -15,16 +16,19 @@ import org.junit.Test;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.impl.VenueImpl;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
public class EventWithNullStartAndEndDataJsonSerializerTest {
@@ -34,15 +38,21 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
protected final TimePoint expectedStartDate = null;
protected final TimePoint expectedEndDate = null;
protected final Venue expectedVenue = new VenueImpl("Expected Venue");
protected final LeaderboardGroupBase expectedLeaderboardGroup = mock(LeaderboardGroupBase.class);
protected final Iterable<LeaderboardGroupBase> expectedLeaderboardGroups = Collections.singleton(expectedLeaderboardGroup);
protected JsonSerializer<Venue> venueSerializer;
protected EventJsonSerializer serializer;
protected EventBaseJsonSerializer serializer;
protected EventBaseJsonDeserializer deserializer;
protected EventBase event;
@Before
public void setUp() {
// Event and its basic attributes ...
when(expectedLeaderboardGroup.getId()).thenReturn(UUID.randomUUID());
when(expectedLeaderboardGroup.getName()).thenReturn("My Leaderboard Group");
when(expectedLeaderboardGroup.getDescription()).thenReturn("This is My Leaderboard Group");
when(expectedLeaderboardGroup.hasOverallLeaderboard()).thenReturn(true);
event = mock(EventBase.class);
when(event.getId()).thenReturn(expectedId);
when(event.getName()).thenReturn(expectedName);
@@ -51,19 +61,20 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
when(event.getVenue()).thenReturn(expectedVenue);
when(event.getImageURLs()).thenReturn(Collections.<URL>emptySet());
when(event.getVideoURLs()).thenReturn(Collections.<URL>emptySet());
doReturn(expectedLeaderboardGroups).when(event).getLeaderboardGroups();
// ... and the serializer itself.
serializer = new EventJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()));
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)));
serializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
}
@Test
public void testBasicAttributes() {
JSONObject result = serializer.serialize(event);
assertEquals(expectedId, UUID.fromString(result.get(EventJsonSerializer.FIELD_ID).toString()));
assertEquals(expectedName, result.get(EventJsonSerializer.FIELD_NAME));
assertNull(result.get(EventJsonSerializer.FIELD_START_DATE));
assertNull(result.get(EventJsonSerializer.FIELD_END_DATE));
assertEquals(expectedId, UUID.fromString(result.get(EventBaseJsonSerializer.FIELD_ID).toString()));
assertEquals(expectedName, result.get(EventBaseJsonSerializer.FIELD_NAME));
assertNull(result.get(EventBaseJsonSerializer.FIELD_START_DATE));
assertNull(result.get(EventBaseJsonSerializer.FIELD_END_DATE));
}
@Test
@@ -72,6 +83,10 @@ public class EventWithNullStartAndEndDataJsonSerializerTest {
final EventBase deserializedEvent = deserializer.deserialize(result);
assertEquals(expectedId, deserializedEvent.getId());
assertEquals(expectedName, deserializedEvent.getName());
LeaderboardGroupBase deserializedLg = deserializedEvent.getLeaderboardGroups().iterator().next();
assertEquals(expectedLeaderboardGroup.getName(), deserializedLg.getName());
assertEquals(expectedLeaderboardGroup.getDescription(), deserializedLg.getDescription());
assertEquals(expectedLeaderboardGroup.hasOverallLeaderboard(), deserializedLg.hasOverallLeaderboard());
assertNull(deserializedEvent.getStartDate());
assertNull(deserializedEvent.getEndDate());
}
@@ -10,44 +10,55 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.impl.EventBaseImpl;
import com.sap.sailing.domain.base.impl.StrippedEventImpl;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.EventJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
private JsonDeserializer<Venue> venueDeserializer;
private final JsonDeserializer<Venue> venueDeserializer;
private final JsonDeserializer<LeaderboardGroupBase> leaderboardGroupDeserializer;
public EventBaseJsonDeserializer(JsonDeserializer<Venue> venueDeserializer) {
public EventBaseJsonDeserializer(JsonDeserializer<Venue> venueDeserializer, JsonDeserializer<LeaderboardGroupBase> leaderboardGroupDeserializer) {
this.venueDeserializer = venueDeserializer;
this.leaderboardGroupDeserializer = leaderboardGroupDeserializer;
}
public EventBase deserialize(JSONObject object) throws JsonDeserializationException {
UUID id = UUID.fromString((String) object.get(EventJsonSerializer.FIELD_ID));
String name = object.get(EventJsonSerializer.FIELD_NAME).toString();
Number startDate = (Number) object.get(EventJsonSerializer.FIELD_START_DATE);
Number endDate = (Number) object.get(EventJsonSerializer.FIELD_END_DATE);
UUID id = UUID.fromString((String) object.get(EventBaseJsonSerializer.FIELD_ID));
String name = object.get(EventBaseJsonSerializer.FIELD_NAME).toString();
Number startDate = (Number) object.get(EventBaseJsonSerializer.FIELD_START_DATE);
Number endDate = (Number) object.get(EventBaseJsonSerializer.FIELD_END_DATE);
final Venue venue;
if (object.get(EventJsonSerializer.FIELD_VENUE) != null) {
JSONObject venueObject = Helpers.getNestedObjectSafe(object, EventJsonSerializer.FIELD_VENUE);
if (object.get(EventBaseJsonSerializer.FIELD_VENUE) != null) {
JSONObject venueObject = Helpers.getNestedObjectSafe(object, EventBaseJsonSerializer.FIELD_VENUE);
venue = venueDeserializer.deserialize(venueObject);
} else {
venue = null;
}
EventBaseImpl result = new EventBaseImpl(name, startDate == null ? null : new MillisecondsTimePoint(startDate.longValue()),
endDate == null ? null : new MillisecondsTimePoint(endDate.longValue()), venue, true, id);
if (object.get(EventJsonSerializer.FIELD_IMAGE_URLS) != null) {
JSONArray leaderboardGroupsJson = (JSONArray) object.get(EventBaseJsonSerializer.FIELDS_LEADERBOARD_GROUPS);
List<LeaderboardGroupBase> leaderboardGroups = new ArrayList<LeaderboardGroupBase>();
if (leaderboardGroupsJson != null) {
for (Object lgJson : leaderboardGroupsJson) {
leaderboardGroups.add(leaderboardGroupDeserializer.deserialize((JSONObject) lgJson));
}
}
EventBaseImpl result = new StrippedEventImpl(name, startDate == null ? null : new MillisecondsTimePoint(startDate.longValue()),
endDate == null ? null : new MillisecondsTimePoint(endDate.longValue()), venue, /* is public */ true, id, leaderboardGroups);
if (object.get(EventBaseJsonSerializer.FIELD_IMAGE_URLS) != null) {
try {
result.setImageURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventJsonSerializer.FIELD_IMAGE_URLS)));
result.setImageURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventBaseJsonSerializer.FIELD_IMAGE_URLS)));
} catch (MalformedURLException e) {
throw new JsonDeserializationException("Error deserializing image URLs for event "+name, e);
}
}
if (object.get(EventJsonSerializer.FIELD_VIDEO_URLS) != null) {
if (object.get(EventBaseJsonSerializer.FIELD_VIDEO_URLS) != null) {
try {
result.setVideoURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventJsonSerializer.FIELD_VIDEO_URLS)));
result.setVideoURLs(getURLsFromStrings(Helpers.getNestedArraySafe(object, EventBaseJsonSerializer.FIELD_VIDEO_URLS)));
} catch (MalformedURLException e) {
throw new JsonDeserializationException("Error deserializing video URLs for event "+name, e);
}
@@ -0,0 +1,27 @@
package com.sap.sailing.server.gateway.deserialization.impl;
import java.util.UUID;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.impl.StrippedLeaderboardGroupImpl;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
public class LeaderboardGroupBaseJsonDeserializer implements JsonDeserializer<LeaderboardGroupBase> {
public LeaderboardGroupBaseJsonDeserializer() {
}
public LeaderboardGroupBase deserialize(JSONObject object) throws JsonDeserializationException {
UUID id = UUID.fromString((String) object.get(EventBaseJsonSerializer.FIELD_ID));
String name = object.get(LeaderboardGroupBaseJsonSerializer.FIELD_NAME).toString();
String description = object.get(LeaderboardGroupBaseJsonSerializer.FIELD_DESCRIPTION).toString();
String hasOverallLeaderboard = object.get(LeaderboardGroupBaseJsonSerializer.FIELD_HAS_OVERALL_LEADERBOARD).toString();
LeaderboardGroupBase result = new StrippedLeaderboardGroupImpl(id, name, description, hasOverallLeaderboard == null ? false : Boolean.valueOf(hasOverallLeaderboard));
return result;
}
}
@@ -6,10 +6,11 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class EventJsonSerializer implements JsonSerializer<EventBase> {
public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_ID = "id";
public static final String FIELD_NAME = "name";
public static final String FIELD_START_DATE = "startDate";
@@ -17,11 +18,13 @@ public class EventJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_VENUE = "venue";
public static final String FIELD_IMAGE_URLS = "imageURLs";
public static final String FIELD_VIDEO_URLS = "videoURLs";
public static final String FIELDS_LEADERBOARD_GROUPS = "leaderboardGroups";
private final JsonSerializer<Venue> venueSerializer;
private final JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupSerializer;
public EventJsonSerializer(JsonSerializer<Venue> venueSerializer)
{
public EventBaseJsonSerializer(JsonSerializer<Venue> venueSerializer, JsonSerializer<? super LeaderboardGroupBase> leaderboardGroupSerializer) {
this.leaderboardGroupSerializer = leaderboardGroupSerializer;
this.venueSerializer = venueSerializer;
}
@@ -34,6 +37,11 @@ public class EventJsonSerializer implements JsonSerializer<EventBase> {
result.put(FIELD_VENUE, venueSerializer.serialize(event.getVenue()));
result.put(FIELD_IMAGE_URLS, getURLsAsStringArray(event.getImageURLs()));
result.put(FIELD_VIDEO_URLS, getURLsAsStringArray(event.getVideoURLs()));
JSONArray leaderboardGroups = new JSONArray();
result.put(FIELDS_LEADERBOARD_GROUPS, leaderboardGroups);
for (LeaderboardGroupBase lg : event.getLeaderboardGroups()) {
leaderboardGroups.add(leaderboardGroupSerializer.serialize(lg));
}
return result;
}
@@ -0,0 +1,25 @@
package com.sap.sailing.server.gateway.serialization.impl;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
public class LeaderboardGroupBaseJsonSerializer implements JsonSerializer<LeaderboardGroupBase> {
public static final String FIELD_ID = "id";
public static final String FIELD_NAME = "name";
public static final String FIELD_DESCRIPTION = "description";
public static final String FIELD_HAS_OVERALL_LEADERBOARD = "hasOverallLeaderboard";
public LeaderboardGroupBaseJsonSerializer() {
}
public JSONObject serialize(LeaderboardGroupBase leaderboardGroup) {
JSONObject result = new JSONObject();
result.put(FIELD_ID, leaderboardGroup.getId().toString());
result.put(FIELD_NAME, leaderboardGroup.getName());
result.put(FIELD_DESCRIPTION, leaderboardGroup.getDescription());
result.put(FIELD_HAS_OVERALL_LEADERBOARD, leaderboardGroup.hasOverallLeaderboard());
return result;
}
}
@@ -12,7 +12,8 @@ import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
public class EventsJsonGetServlet extends AbstractJsonHttpServlet {
@@ -20,7 +21,7 @@ public class EventsJsonGetServlet extends AbstractJsonHttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
JsonSerializer<EventBase> eventSerializer = new EventJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()));
JsonSerializer<EventBase> eventSerializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseJsonSerializer());
JSONArray result = new JSONArray();
for (EventBase event : getService().getAllEvents()) {
result.add(eventSerializer.serialize(event));
@@ -18,7 +18,7 @@ import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.server.gateway.jaxrs.AbstractSailingServerResource;
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.CourseAreaJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer;
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
@Path("/v1/events")
@@ -31,7 +31,7 @@ public class EventsResource extends AbstractSailingServerResource {
@GET
@Produces("application/json;charset=UTF-8")
public Response getEvents() {
JsonSerializer<EventBase> eventSerializer = new EventJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()));
JsonSerializer<EventBase> eventSerializer = new EventBaseJsonSerializer(new VenueJsonSerializer(new CourseAreaJsonSerializer()), new LeaderboardGroupBaseSerializer());
JSONArray result = new JSONArray();
for (EventBase event : getService().getAllEvents()) {
if (event.isPublic()) {
@@ -57,8 +57,8 @@ public class EventsResource extends AbstractSailingServerResource {
if (event == null) {
response = getBadEventErrorResponse(eventId);
} else {
JsonSerializer<EventBase> eventSerializer = new EventJsonSerializer(new VenueJsonSerializer(
new CourseAreaJsonSerializer()));
JsonSerializer<EventBase> eventSerializer = new EventBaseJsonSerializer(new VenueJsonSerializer(
new CourseAreaJsonSerializer()), new LeaderboardGroupBaseSerializer());
JSONObject eventJson = eventSerializer.serialize(event);
String json = eventJson.toJSONString();
@@ -28,6 +28,7 @@ import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
/**
@@ -95,7 +96,7 @@ public class RemoteSailingServerSet {
JSONParser parser = new JSONParser();
Object eventsAsObject = parser.parse(bufferedReader);
EventBaseJsonDeserializer deserializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(
new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)));
new CourseAreaJsonDeserializer(DomainFactory.INSTANCE)), new LeaderboardGroupBaseJsonDeserializer());
JSONArray eventsAsJsonArray = (JSONArray) eventsAsObject;
final Set<EventBase> events = new HashSet<>();
for (Object eventAsObject : eventsAsJsonArray) {
@@ -35,6 +35,28 @@
<h2 class="articleHeadline">Analyzing Races, Leaderboards</h2>
<div class="innerContent">
<h2 class="articleSubheadline">June 2014</h2>
<ul class="bulletList">
<li>Switched to the latest version of the Highcharts charting framework. This leads to improvements
especially on mobile devices. Charts can be zoomed using pinch gestures now.
</li>
<li>To support the use of the SAP Sailing Analytics also for live video streaming formats, we
introduced a new URL parameter <tt>viewShowMapControls</tt> for the <tt>Spectator.html</tt>
and the <tt>RaceBoard.html</tt> pages. Setting this parameter to "false"
will suppress the zoom, pan and map type selection
controls on the map display. Example:
<a href="http://danishleague2014.sapsailing.com/gwt/Spectator.html?leaderboardGroupName=Danish%20League%202014&showRaceDetails=true&viewShowMapControls=false">http://danishleague2014.sapsailing.com/gwt/Spectator.html?leaderboardGroupName=Danish%20League%202014&showRaceDetails=true&viewShowMapControls=false</a>.
When used for the <tt>Spectator.html</tt> URL, this will apply
to all <tt>RaceBoard.html</tt> pages (all races) reached from there. Of course, the map
can still be panned and zoomed using the usual mouse gestures. A left double click zooms
in, a right double click zooms out. Zoom can also be controlled using the mouse wheel.
And panning works by clicking on the map and dragging the mouse. Without the map type
control, switching to satellite view is not possible (keep this in mind when tracking
races in China, see below for Google's random coordinate transformations there).
</li>
</ul>
<h2 class="articleSubheadline">May 2014</h2>
<ul class="bulletList">
@@ -17,6 +17,7 @@ java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# Overwrite the log leves for specific loggers here
com.sap.sailing.level = FINE
com.sap.sailing.domain.tracking.impl.level = FINEST
org.eclipse.jetty.level = INFO
org.apache.activemq.level = INFO
@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@@ -17,6 +18,7 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.LeaderboardGroupBase;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
@@ -30,6 +32,7 @@ import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.EventBaseImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.StrippedEventImpl;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.base.racegroup.SeriesWithRows;
import com.sap.sailing.domain.base.racegroup.impl.RaceGroupImpl;
@@ -74,10 +77,10 @@ public class OfflineDataManager extends DataManager {
cal.set(2012, 12, 5);
final TimePoint endDate = new MillisecondsTimePoint(cal.getTimeInMillis());
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Cardiff)", startDate, endDate, "Cardiff", true, UUID.randomUUID()));
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Nice)", startDate, endDate, "Nice", true, UUID.randomUUID()));
dataStore.addEvent(new EventBaseImpl("Extreme Sailing Series 2012 (Rio)", startDate, endDate, "Rio", true, UUID.randomUUID()));
EventBase newEvent = new EventBaseImpl("Extreme Sailing Series 2013 (Muscat)", startDate, endDate, "Muscat", true, UUID.randomUUID());
dataStore.addEvent(new StrippedEventImpl("Extreme Sailing Series 2012 (Cardiff)", startDate, endDate, "Cardiff", true, UUID.randomUUID(), Collections.<LeaderboardGroupBase>emptySet()));
dataStore.addEvent(new StrippedEventImpl("Extreme Sailing Series 2012 (Nice)", startDate, endDate, "Nice", true, UUID.randomUUID(), Collections.<LeaderboardGroupBase>emptySet()));
dataStore.addEvent(new StrippedEventImpl("Extreme Sailing Series 2012 (Rio)", startDate, endDate, "Rio", true, UUID.randomUUID(), Collections.<LeaderboardGroupBase>emptySet()));
EventBase newEvent = new StrippedEventImpl("Extreme Sailing Series 2013 (Muscat)", startDate, endDate, "Muscat", true, UUID.randomUUID(), Collections.<LeaderboardGroupBase>emptySet());
newEvent.getVenue().addCourseArea(new CourseAreaImpl("Offshore", UUID.randomUUID()));
newEvent.getVenue().addCourseArea(new CourseAreaImpl("Stadium", UUID.randomUUID()));
dataStore.addEvent(newEvent);
@@ -101,7 +101,7 @@ public class OnlineDataManager extends DataManager {
@Override
public Loader<DataLoaderResult<Collection<EventBase>>> create(int id, Bundle args) throws Exception {
DataParser<Collection<EventBase>> parser = new EventsDataParser(new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory))));
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory)), leaderboardGroupDeserializer));
DataHandler<Collection<EventBase>> handler = new EventsDataHandler(OnlineDataManager.this);
ExLog.i(TAG, "getEventsLoader created new loader...");