Merge branch 'master' into racecommittee_app

This commit is contained in:
Armin Zamani committed 2013-06-05 01:18:57 +02:00
commit ef563555d0
27 files changed
+1678 -1409

No files matched your search

+6 -5
View File
@@ -338,17 +338,18 @@ if [[ "$@" == "install" ]] || [[ "$@" == "all" ]]; then
rm -rf $ACDIR/configuration/org.eclipse.*
if [[ $HAS_OVERWRITTEN_TARGET -eq 0 ]]; then
rm -rf $ACDIR/start
rm -rf $ACDIR/stop
cp -v $p2PluginRepository/configuration/config.ini configuration/
mkdir -p configuration/jetty/etc
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/jetty.xml configuration/jetty/etc
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/realm.properties configuration/jetty/etc
cp -v $PROJECT_HOME/java/target/configuration/monitoring.properties configuration/
cp -v $PROJECT_HOME/configuration/mongodb.cfg $ACDIR/
cp -v $PROJECT_HOME/java/target/start $ACDIR/
cp -v $PROJECT_HOME/java/target/stop $ACDIR/
# avoid overwriting start configuration if it exists
if [ ! -f $ACDIR/start ]; then
cp -v $PROJECT_HOME/java/target/start $ACDIR/
cp -v $PROJECT_HOME/java/target/stop $ACDIR/
fi
fi
cp -r -v $p2PluginRepository/configuration/org.eclipse.equinox.simpleconfigurator configuration/
+44 -44
View File
@@ -1,44 +1,44 @@
#!/bin/bash
command -v tmux >/dev/null 2>&1 || { echo "I require tmux but it's not installed. Aborting." >&2; exit 1; }
sn=sailing
SERVERS_DIR=/home/trac/servers
TMUX_ACTIVE=`tmux has-session -t $sn 2>/dev/null`
if [ $? -eq 0 ]; then
echo "Session exists...not configuring a new one"
else
echo "Session does not exist...creating a new one with name $sn"
cd /home/trac/git
tmux new-session -s "$sn" -n "BUILD" -d
counter=1
for dir in dev test prod1 prod2; do
cd $SERVERS_DIR/$dir
tmux new-window -t "$sn:$counter" -n `basename $dir` "bash -c './start'; bash"
counter=$[counter + 1]
done
cd /home/trac/servers/prod1
tmux new-window -t "$sn:$counter" -n "UDP" "bash -c './udpmirror -v 2012 localhost 2010 localhost 2011 localhost 2013 localhost 2014'; bash"
cd /opt/mongodb/bin
tmux new-window -t "$sn:$[counter+1]" -n "GOAccess" "bash -c 'goaccess -f /var/log/httpd/access_log'; bash"
cd /opt/
tmux new-window -t "$sn:$[counter+2]" -n "ATop" "bash -c 'apachetop -f /var/log/httpd/access_log'; bash"
cd /home/trac/servers
tmux new-window -t "$sn:$[counter+3]" -n "Logs" "bash -c 'ls -lah'; bash"
cd /home/trac/servers/prod1
tmux new-window -t "$sn:$[counter+4]" -n "STListener" "bash -c './swisstiminglistener 3500 3501'; bash"
tmux select-window -t "$sn:0"
fi
if [[ "$1" != "unattended" ]]; then
tmux -2 attach-session -t "$sn"
fi
#!/bin/bash
command -v tmux >/dev/null 2>&1 || { echo "I require tmux but it's not installed. Aborting." >&2; exit 1; }
sn=sailing
SERVERS_DIR=/home/trac/servers
TMUX_ACTIVE=`tmux has-session -t $sn 2>/dev/null`
if [ $? -eq 0 ]; then
echo "Session exists...not configuring a new one"
else
echo "Session does not exist...creating a new one with name $sn"
cd /home/trac/git
tmux new-session -s "$sn" -n "BUILD" -d
counter=1
for dir in dev test prod1 prod2; do
cd $SERVERS_DIR/$dir
tmux new-window -t "$sn:$counter" -n `basename $dir` "bash -c './start'; bash"
counter=$[counter + 1]
done
cd /home/trac/servers/prod1
tmux new-window -t "$sn:$counter" -n "UDP" "bash -c './udpmirror -v 2012 localhost 2010 localhost 2011 localhost 2013 localhost 2014'; bash"
cd /opt/mongodb/bin
tmux new-window -t "$sn:$[counter+1]" -n "GOAccess" "bash -c 'goaccess -f /var/log/httpd/access_log'; bash"
cd /opt/
tmux new-window -t "$sn:$[counter+2]" -n "ATop" "bash -c 'apachetop -f /var/log/httpd/access_log'; bash"
cd /home/trac/servers
tmux new-window -t "$sn:$[counter+3]" -n "Logs" "bash -c 'ls -lah'; bash"
cd /home/trac/servers/prod1
tmux new-window -t "$sn:$[counter+4]" -n "STListener" "bash -c './swisstiminglistener 3500 3501'; bash"
tmux select-window -t "$sn:0"
fi
if [[ "$1" != "unattended" ]]; then
tmux -2 attach-session -t "$sn"
fi
@@ -2,5 +2,5 @@ package com.sap.sailing.domain.common;
public enum ScoringSchemeType {
LOW_POINT, HIGH_POINT, HIGH_POINT_ESS_OVERALL, HIGH_POINT_LAST_BREAKS_TIE,
HIGH_POINT_FIRST_GETS_TEN, LOW_POINT_WINNER_GETS_ZERO
HIGH_POINT_FIRST_GETS_TEN, HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO
}
@@ -2,10 +2,13 @@ package com.sap.sailing.domain.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -13,17 +16,22 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.common.impl.Util;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
@@ -33,7 +41,9 @@ import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithFixedRank;
import com.sap.sailing.domain.test.mock.MockedTrackedRaceWithFixedRankAndManyCompetitors;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
private Set<TrackedRace> testRaces;
@@ -100,6 +110,51 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
leaderboard.addRace(testRaces.iterator().next(), columnName, /* medalRace */ false, defaultFleet);
assertTrue(leaderboard.getRaceColumnByName(columnName).isMedalRace());
}
@Test
public void testRepeatedLeaderboardDTOCacheInvalidation() throws NoWindException, InterruptedException, ExecutionException {
FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("Test Leaderboard", new ScoreCorrectionImpl(), new ResultDiscardingRuleImpl(
new int[] { 5, 8 }), new LowPoint(), null);
Fleet defaultFleet = leaderboard.getFleet(null);
final String columnName = "abc";
setupRaces(1, 0);
leaderboard.addRaceColumn(columnName, /* medalRace */ true);
leaderboard.addRace(testRaces.iterator().next(), columnName, /* medalRace */ false, defaultFleet);
final Set<String> emptySet = Collections.emptySet();
final MillisecondsTimePoint now = MillisecondsTimePoint.now();
final TrackedRegattaRegistry trackedRegattaRegistry = new TrackedRegattaRegistry() {
@Override
public DynamicTrackedRegatta getOrCreateTrackedRegatta(Regatta regatta) {
return null;
}
@Override
public DynamicTrackedRegatta getTrackedRegatta(Regatta regatta) {
return null;
}
@Override
public void removeTrackedRegatta(Regatta regatta) {}
@Override
public Regatta getRememberedRegattaForRace(Serializable raceID) {
return null;
}
@Override
public boolean isRaceBeingTracked(RaceDefinition r) {
return true;
}
};
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE);
assertNotNull(leaderboardDTO);
assertSame(leaderboardDTO, leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE)); // assert it's cached
leaderboard.getRaceColumnByName(columnName).releaseTrackedRace(defaultFleet); // this should clear the cache
LeaderboardDTO leaderboardDTO2 = leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE);
assertNotSame(leaderboardDTO, leaderboardDTO2);
assertSame(leaderboardDTO2, leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE)); // and cached again
leaderboard.getRaceColumnByName(columnName).setTrackedRace(defaultFleet, testRaces.iterator().next()); // clear cache again; requires listener(s) to still be attached
LeaderboardDTO leaderboardDTO3 = leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE);
assertNotSame(leaderboardDTO2, leaderboardDTO3);
assertSame(leaderboardDTO3, leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE)); // and cached again
}
@Test
public void testMaxPointsDiscard() throws NoWindException {
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.test.mock;
import java.io.Serializable;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
@@ -191,8 +192,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor) {
// TODO Auto-generated method stub
return null;
return new TreeSet<MarkPassing>();
}
@Override
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.test.mock;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -8,6 +9,8 @@ import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint;
@@ -33,6 +36,11 @@ public class MockedTrackedRaceWithFixedRank extends MockedTrackedRace {
private class MockedRaceDefinition implements RaceDefinition {
private static final long serialVersionUID = 6812543850545870357L;
private final Course course;
public MockedRaceDefinition() {
course = new CourseImpl("Test Course", Arrays.asList(new Waypoint[0]));
}
@Override
public String getName() {
@@ -41,7 +49,7 @@ public class MockedTrackedRaceWithFixedRank extends MockedTrackedRace {
@Override
public Course getCourse() {
return null;
return course;
}
@Override
@@ -101,7 +101,7 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
@Override
public synchronized void releaseTrackedRace(Fleet fleet) {
trackedRaces.remove(fleet);
setTrackedRace(fleet, null);
}
@Override
@@ -56,6 +56,7 @@ import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
import com.sap.sailing.domain.leaderboard.impl.HighPointExtremeSailingSeriesOverall;
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets10LastBreaksTie;
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets1LastBreaksTie;
import com.sap.sailing.domain.leaderboard.impl.HighPointLastBreaksTie;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.leaderboard.impl.LowPointWinnerGetsZero;
@@ -320,6 +321,8 @@ public class DomainFactoryImpl implements DomainFactory {
return new HighPointExtremeSailingSeriesOverall();
case HIGH_POINT_LAST_BREAKS_TIE:
return new HighPointLastBreaksTie();
case HIGH_POINT_FIRST_GETS_ONE:
return new HighPointFirstGets1LastBreaksTie();
case HIGH_POINT_FIRST_GETS_TEN:
return new HighPointFirstGets10LastBreaksTie();
case LOW_POINT_WINNER_GETS_ZERO:
@@ -180,94 +180,101 @@ public class LeaderboardCacheManager {
* is updated accordingly.
*/
private void registerAsListener(final Leaderboard leaderboard) {
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
registerListener(leaderboard, trackedRace);
}
final CacheInvalidationUponScoreCorrectionListener scoreCorrectionListener = new CacheInvalidationUponScoreCorrectionListener(leaderboard);
leaderboard.getScoreCorrection().addScoreCorrectionListener(scoreCorrectionListener);
synchronized (scoreCorrectionListeners) {
scoreCorrectionListeners.put(leaderboard, scoreCorrectionListener);
}
final RaceColumnListener raceColumnListener = new RaceColumnListener() {
private static final long serialVersionUID = 8165124797028386317L;
@Override
public void trackedRaceLinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
removeFromCache(leaderboard);
// only add as listener again if not yet added
if (!scoreCorrectionListeners.containsKey(leaderboard)) {
for (TrackedRace trackedRace : leaderboard.getTrackedRaces()) {
registerListener(leaderboard, trackedRace);
}
/**
* This listener must not be serialized. See also bug 952.
*/
@Override
public boolean isTransient() {
return true;
final CacheInvalidationUponScoreCorrectionListener scoreCorrectionListener = new CacheInvalidationUponScoreCorrectionListener(
leaderboard);
leaderboard.getScoreCorrection().addScoreCorrectionListener(scoreCorrectionListener);
synchronized (scoreCorrectionListeners) {
scoreCorrectionListeners.put(leaderboard, scoreCorrectionListener);
}
@Override
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
removeFromCache(leaderboard);
Map<TrackedRace, Set<CacheInvalidationListener>> listenersMap = invalidationListenersPerLeaderboard.get(leaderboard);
if (listenersMap != null) {
Set<CacheInvalidationListener> listeners = listenersMap.get(trackedRace);
if (listeners != null) {
for (CacheInvalidationListener listener : listeners) {
listener.removeFromTrackedRace();
final RaceColumnListener raceColumnListener = new RaceColumnListener() {
private static final long serialVersionUID = 8165124797028386317L;
@Override
public void trackedRaceLinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
removeFromCache(leaderboard);
registerListener(leaderboard, trackedRace);
}
/**
* This listener must not be serialized. See also bug 952.
*/
@Override
public boolean isTransient() {
return true;
}
@Override
public void trackedRaceUnlinked(RaceColumn raceColumn, Fleet fleet, TrackedRace trackedRace) {
removeFromCache(leaderboard);
Map<TrackedRace, Set<CacheInvalidationListener>> listenersMap = invalidationListenersPerLeaderboard
.get(leaderboard);
if (listenersMap != null) {
Set<CacheInvalidationListener> listeners = listenersMap.get(trackedRace);
if (listeners != null) {
for (CacheInvalidationListener listener : listeners) {
listener.removeFromTrackedRace();
}
}
}
}
}
@Override
public void isMedalRaceChanged(RaceColumn raceColumn, boolean newIsMedalRace) {
removeFromCache(leaderboard);
}
@Override
public void isMedalRaceChanged(RaceColumn raceColumn, boolean newIsMedalRace) {
removeFromCache(leaderboard);
}
@Override
public boolean canAddRaceColumnToContainer(RaceColumn raceColumn) {
return true;
}
@Override
public boolean canAddRaceColumnToContainer(RaceColumn raceColumn) {
return true;
}
@Override
public void raceColumnAddedToContainer(RaceColumn raceColumn) {
removeFromCache(leaderboard);
}
@Override
public void raceColumnAddedToContainer(RaceColumn raceColumn) {
removeFromCache(leaderboard);
}
@Override
public void raceColumnRemovedFromContainer(RaceColumn raceColumn) {
removeFromCache(leaderboard);
}
@Override
public void raceColumnRemovedFromContainer(RaceColumn raceColumn) {
removeFromCache(leaderboard);
}
@Override
public void raceColumnMoved(RaceColumn raceColumn, int newIndex) {
removeFromCache(leaderboard);
}
@Override
public void raceColumnMoved(RaceColumn raceColumn, int newIndex) {
removeFromCache(leaderboard);
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
removeFromCache(leaderboard);
}
@Override
public void factorChanged(RaceColumn raceColumn, Double oldFactor, Double newFactor) {
removeFromCache(leaderboard);
}
@Override
public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
ThresholdBasedResultDiscardingRule newDiscardingRule) {
removeFromCache(leaderboard);
}
@Override
public void resultDiscardingRuleChanged(ThresholdBasedResultDiscardingRule oldDiscardingRule,
ThresholdBasedResultDiscardingRule newDiscardingRule) {
removeFromCache(leaderboard);
}
@Override
public void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName, String displayName) {
removeFromCache(leaderboard);
@Override
public void competitorDisplayNameChanged(Competitor competitor, String oldDisplayName,
String displayName) {
removeFromCache(leaderboard);
}
@Override
public void raceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier,
RaceLogEvent event) {
removeFromCache(leaderboard);
}
};
leaderboard.addRaceColumnListener(raceColumnListener);
synchronized (raceColumnListeners) {
raceColumnListeners.put(leaderboard, raceColumnListener);
}
@Override
public void raceLogEventAdded(RaceColumn raceColumn, RaceLogIdentifier raceLogIdentifier, RaceLogEvent event) {
removeFromCache(leaderboard);
}
};
leaderboard.addRaceColumnListener(raceColumnListener);
synchronized (raceColumnListeners) {
raceColumnListeners.put(leaderboard, raceColumnListener);
}
}
@@ -88,7 +88,6 @@ public class LeaderboardDTOCache implements LeaderboardCache {
}
};
this.leaderboardCacheManager = new LeaderboardCacheManager(this);
this.leaderboardCacheManager.add(leaderboard);
}
@Override
@@ -159,6 +158,7 @@ public class LeaderboardDTOCache implements LeaderboardCache {
}
});
computeLeadearboardByNameExecutor.execute(future);
this.leaderboardCacheManager.add(leaderboard); // ensure the leaderboard is tracked for changes to invalidate
leaderboardCache.put(key, future);
} else {
cacheHit = true;
@@ -0,0 +1,34 @@
package com.sap.sailing.domain.leaderboard.impl;
import java.util.List;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.domain.leaderboard.NumberOfCompetitorsInLeaderboardFetcher;
public class HighPointFirstGets1LastBreaksTie extends HighPointFirstGetsFixedScore {
private static final long serialVersionUID = 1L;
public HighPointFirstGets1LastBreaksTie() {
super(1.0);
}
@Override
public ScoringSchemeType getType() {
return ScoringSchemeType.HIGH_POINT_FIRST_GETS_ONE;
}
@Override
public Double getPenaltyScore(RaceColumn raceColumn, Competitor competitor, MaxPointsReason maxPointsReason, Integer numberOfCompetitorsInRace,
NumberOfCompetitorsInLeaderboardFetcher numberOfCompetitorsInLeaderboardFetcher) {
return -1.0;
}
@Override
public int compareByBetterScore(List<Pair<RaceColumn, Double>> o1Scores, List<Pair<RaceColumn, Double>> o2Scores, boolean nullScoresAreBetter) {
return 0;
}
}
@@ -670,7 +670,9 @@ DynamicTrackedRace, GPSTrackListener<Competitor, GPSFixMoving> {
@Override
public void detachRaceLog() {
logListener.removeFrom(attachedRaceLog);
if (attachedRaceLog != null) {
logListener.removeFrom(attachedRaceLog);
}
super.detachRaceLog();
}
@@ -49,7 +49,9 @@ public class DynamicTrackedRaceLogListener implements RaceLogEventVisitor {
// Maybe something like this is needed:
// TODO:
// ??? trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.PREPARED, 0.0));
raceLog.removeListener(this);
if (raceLog != null) {
raceLog.removeListener(this);
}
}
private void analyze() {
File diff suppressed because it is too large. Load diff
@@ -449,6 +449,7 @@ public interface StringMessages extends Messages {
String sideToWhichMarkAtLegStartWasRounded();
String raceIsLive(String raceName);
String racesAreLive(String raceNames);
String scoringSchemeHighPointFirstGetsOne();
String scoringSchemeHighPointFirstGetsTen();
String knotsUnit();
String averageJibeLossInMetersTooltip();
@@ -490,6 +490,7 @@ sideToWhichMarkAtLegStartWasRoundedTooltip=Side to which the mark at leg start w
raceIsLive=Race {0} is live
racesAreLive=Races {0} are live
knotsUnit=kts
scoringSchemeHighPointFirstGetsOne=High Point, winner gets 1 point
scoringSchemeHighPointFirstGetsTen=High Point, winner gets 10 points
knotsUnit=kts
generatePolarSheet=Generate Polar Sheet
@@ -490,6 +490,7 @@ sideToWhichMarkAtLegStartWasRounded=Tonne gerundet an
sideToWhichMarkAtLegStartWasRoundedTooltip=Seite, an der die Bahnmarke am Schenkelstart gerundet wurde
raceIsLive=Rennen {0} ist live
racesAreLive=Rennen {0} sind live
scoringSchemeHighPointFirstGetsOne=High Point System, Gewinner erhält 1 Punkt
scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte
knotsUnit=kn
generatePolarSheet=Polardiagramm erstellen
@@ -14,6 +14,8 @@ public class ScoringSchemeTypeFormatter {
return stringMessages.scoringSchemeHighPointEssOverall();
case HIGH_POINT_LAST_BREAKS_TIE:
return stringMessages.scoringSchemeHighPointLastBreaksTie();
case HIGH_POINT_FIRST_GETS_ONE:
return stringMessages.scoringSchemeHighPointFirstGetsOne();
case HIGH_POINT_FIRST_GETS_TEN:
return stringMessages.scoringSchemeHighPointFirstGetsTen();
case LOW_POINT_WINNER_GETS_ZERO:
@@ -15,12 +15,13 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions;
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.sap.sailing.domain.common.PolarSheetsData;
import com.sap.sailing.gwt.ui.client.StringMessages;
public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize {
public class PolarSheetsChartPanel extends DockLayoutPanel {
private StringMessages stringMessages;
private Chart chart;
@@ -29,17 +30,18 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize
private Map<Series, String> nameForSeries = new HashMap<Series, String>();
public PolarSheetsChartPanel(StringMessages stringMessages) {
super(Unit.PCT);
this.stringMessages = stringMessages;
setPixelSize(800, 800);
setSize("100%", "100%");
chart = createPolarSheetChart();
seriesMap = new HashMap<String, Series[]>();
setWidget(chart);
add(chart);
}
private Chart createPolarSheetChart() {
Chart polarSheetChart = new Chart().setType(Series.Type.LINE)
.setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y)
.setPolar(true).setSize(800, 800);
.setPolar(true).setHeight100().setWidth100();
polarSheetChart.setChartTitleText(stringMessages.polarSheetChart());
polarSheetChart.getYAxis().setMin(0);
return polarSheetChart;
@@ -167,12 +169,6 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize
chart.setSeriesPlotOptions(new SeriesPlotOptions().setPointMouseOverEventHandler(pointMouseOverHandler));
}
@Override
public void onResize() {
chart.setSizeToMatchContainer();
chart.redraw();
}
public Series[] getSeriesPerWindspeedForName(String name) {
return seriesMap.get(name);
}
@@ -180,5 +176,24 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize
public String getNameForSeries(Series series) {
return nameForSeries.get(series);
}
@Override
protected void onLoad() {
Timer timer = new Timer() {
@Override
public void run() {
chart.setSizeToMatchContainer();
}
};
timer.schedule(200);
super.onLoad();
}
@Override
public void onResize() {
chart.setSizeToMatchContainer();
super.onResize();
}
}
@@ -4,12 +4,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.sap.sailing.gwt.ui.client.AbstractEntryPoint;
import com.sap.sailing.gwt.ui.client.RegattaDisplayer;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
@@ -31,16 +27,11 @@ public class PolarSheetsEntryPoint extends AbstractEntryPoint implements Regatta
}
private void createUI() {
RootPanel rootPanel = RootPanel.get();
DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.PX);
RootLayoutPanel.get().add(mainPanel);
ScrollPanel contentScrollPanel = new ScrollPanel();
RootLayoutPanel rootPanel = RootLayoutPanel.get();
PolarSheetsPanel polarSheetsPanel = new PolarSheetsPanel(sailingService, this, stringMessages, this);
polarSheetsPanel.addStyleName(PolarSheetsPanel.POLARSHEETS_STYLE);
regattaDisplayers.add(polarSheetsPanel);
contentScrollPanel.setWidget(polarSheetsPanel);
mainPanel.add(contentScrollPanel);
rootPanel.add(mainPanel);
rootPanel.add(polarSheetsPanel);
}
@Override
@@ -10,26 +10,28 @@ import org.moxieapps.gwt.highcharts.client.Series;
import org.moxieapps.gwt.highcharts.client.Series.Type;
import org.moxieapps.gwt.highcharts.client.labels.XAxisLabels;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.sap.sailing.domain.common.PolarSheetsHistogramData;
import com.sap.sailing.gwt.ui.client.StringMessages;
public class PolarSheetsHistogramPanel extends SimplePanel implements RequiresResize{
public class PolarSheetsHistogramPanel extends DockLayoutPanel {
private final Chart chart;
private final StringMessages stringMessages;
public PolarSheetsHistogramPanel(StringMessages stringMessages) {
super(Unit.PCT);
this.stringMessages = stringMessages;
setSize("100%", "100%");
chart = createHistogramChart();
chart.getElement().setAttribute("align", "top");
setWidget(chart);
add(chart);
}
private Chart createHistogramChart() {
Chart histogramChart = new Chart().setType(Type.COLUMN).setZoomType(Chart.ZoomType.X).setWidth(800);
Chart histogramChart = new Chart().setType(Type.COLUMN).setZoomType(Chart.ZoomType.X).setHeight100().setWidth100();
histogramChart.setChartTitleText(stringMessages.histogram());
histogramChart.getYAxis().setMin(0).setAxisTitle(new AxisTitle().setText(stringMessages.numberOfDataPoints()));
histogramChart.getXAxis().setLabels(new XAxisLabels().setRotation(-90f).setY(10)).setAxisTitle(new AxisTitle().setText(
@@ -58,10 +60,24 @@ public class PolarSheetsHistogramPanel extends SimplePanel implements RequiresRe
return points;
}
@Override
protected void onLoad() {
Timer timer = new Timer() {
@Override
public void run() {
chart.setSizeToMatchContainer();
}
};
timer.schedule(200);
super.onLoad();
}
@Override
public void onResize() {
chart.setSizeToMatchContainer();
chart.redraw();
super.onResize();
}
}
@@ -10,6 +10,7 @@ import org.moxieapps.gwt.highcharts.client.Series;
import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEvent;
import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEventHandler;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
@@ -17,11 +18,11 @@ import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
import com.sap.sailing.domain.common.PolarSheetsData;
@@ -37,12 +38,11 @@ import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeListener, RegattaDisplayer {
public class PolarSheetsPanel extends SplitLayoutPanel implements RaceSelectionChangeListener, RegattaDisplayer {
// TODO UI stuff
public static final String POLARSHEETS_STYLE = "polarSheets";
private FlowPanel mainPanel;
private SailingServiceAsync sailingService;
private PolarSheetsTrackedRacesList polarSheetsTrackedRacesList;
private ErrorReporter errorReporter;
@@ -64,6 +64,8 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
private ListBox nameListBox;
private ScrollPanel leftScrollPanel;
public PolarSheetsPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages, PolarSheetsEntryPoint polarSheetsEntryPoint) {
this.polarSheetsEntryPoint = polarSheetsEntryPoint;
@@ -73,28 +75,27 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
idNameMapping = new HashMap<String, String>();
nameIdMapping = new HashMap<String, String>();
this.mainPanel = new FlowPanel();
setSize("100%", "100%");
mainPanel.setSize("100%", "100%");
setWidget(mainPanel);
HorizontalPanel splitPanel = createSplitPanel();
VerticalPanel leftPanel = addFilteredTrackedRacesList(splitPanel);
VerticalPanel leftPanel = addFilteredTrackedRacesList();
leftScrollPanel = new ScrollPanel(leftPanel);
addWest(leftScrollPanel, 400);
polarSheetsGenerationLabel = createPolarSheetGenerationStatusLabel();
leftPanel.add(polarSheetsGenerationLabel);
dataCountLabel = new Label();
leftPanel.add(dataCountLabel);
VerticalPanel rightPanel = addPolarSheetsChartPanel(splitPanel);
DockLayoutPanel rightPanel = new DockLayoutPanel(Unit.PCT);
PolarSheetsChartPanel polarSheetsChartPanel = createPolarSheetsChartPanel();
rightPanel.addNorth(polarSheetsChartPanel, 70);
histogramPanel = new PolarSheetsHistogramPanel(stringMessages);
histogramPanel.getElement().setAttribute("align", "top");
rightPanel.add(histogramPanel);
rightPanel.addSouth(histogramPanel, 30);
nameListBox = new ListBox();
rightPanel.add(nameListBox);
leftPanel.add(nameListBox);
Button exportButton = new Button("Export");
setExportButtonListener(exportButton);
rightPanel.add(exportButton);
mainPanel.add(splitPanel);
leftPanel.add(exportButton);
add(rightPanel);
asyncActionsExecutor = new AsyncActionsExecutor();
setEventListenersForPolarSheetChart();
@@ -221,32 +222,17 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
return polarSheetsGenerationStatusLabel;
}
private VerticalPanel addPolarSheetsChartPanel(HorizontalPanel splitPanel) {
VerticalPanel verticalPanel = new VerticalPanel();
verticalPanel.setSize("100%", "100%");
private PolarSheetsChartPanel createPolarSheetsChartPanel() {
chartPanel = new PolarSheetsChartPanel(stringMessages);
verticalPanel.add(chartPanel);
verticalPanel.setCellHeight(chartPanel, "800px");
splitPanel.add(verticalPanel);
splitPanel.setCellWidth(verticalPanel, "50%");
return verticalPanel;
return chartPanel;
}
private HorizontalPanel createSplitPanel() {
HorizontalPanel splitPanel = new HorizontalPanel();
splitPanel.setSize("100%", "100%");
return splitPanel;
}
private VerticalPanel addFilteredTrackedRacesList(HorizontalPanel splitPanel) {
private VerticalPanel addFilteredTrackedRacesList() {
VerticalPanel trackedRacesPanel = new VerticalPanel();
trackedRacesPanel.setWidth("100%");
createPolarSheetsTrackedRacesList();
trackedRacesPanel.add(polarSheetsTrackedRacesList);
splitPanel.add(trackedRacesPanel);
splitPanel.setCellWidth(trackedRacesPanel, "50%");
return trackedRacesPanel;
}
@@ -351,4 +337,26 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi
polarSheetsTrackedRacesList.fillRegattas(regattas);
}
@Override
protected void onLoad() {
Timer timer = new Timer() {
@Override
public void run() {
setWidgetSize(leftScrollPanel, polarSheetsTrackedRacesList.getOffsetWidth() + 30);
Timer timer = new Timer() {
@Override
public void run() {
chartPanel.onResize();
histogramPanel.onResize();
}
};
timer.schedule(200);
}
};
timer.schedule(600);
super.onLoad();
}
}
@@ -19,15 +19,16 @@ import com.sap.sailing.selenium.test.adminconsole.pages.LeaderboardConfiguration
* D049941
*/
public class TestLeaderboardCreation extends AbstractSeleniumTest {
@Before
public void clearDatabase() {
DatabaseHelper.dropDatabase();
}
// @Before
// public void clearDatabase() {
// DatabaseHelper.dropDatabase();
// }
@Test
public void testCreateFlexibleLeaderboardWithDuplicateName() {
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
LeaderboardConfigurationPanel leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration();
leaderboardConfiguration.deleteLeaderboard("Humba Humba");
{
FlexibleLeaderboardCreationDialog dialog = leaderboardConfiguration.startCreatingFlexibleLeaderboard();
dialog.setName("Humba Humba");
@@ -1,28 +1,81 @@
package com.sap.sailing.selenium.test.adminconsole.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import com.sap.sailing.selenium.core.BySeleniumId;
import com.sap.sailing.selenium.core.FindBy;
import com.sap.sailing.selenium.test.PageArea;
public class LeaderboardConfigurationPanel extends PageArea {
@FindBy(how = BySeleniumId.class, using = "CreateFlexibleLeaderboardButton")
private WebElement createFlexibleLeaderboardButton;
@FindBy(how = BySeleniumId.class, using = "CreateRegattaLeaderboardButton")
private WebElement createRegattaLeaderboardButton;
protected LeaderboardConfigurationPanel(WebDriver driver, WebElement element) {
super(driver, element);
}
public FlexibleLeaderboardCreationDialog startCreatingFlexibleLeaderboard() {
this.createFlexibleLeaderboardButton.click();
// Wait, since we trigger an AJAX-request to get the available events
waitForAjaxRequests();
WebElement dialog = findElementBySeleniumId(this.driver, "CreateFlexibleLeaderboardDialog");
return new FlexibleLeaderboardCreationDialog(this.driver, dialog);
}
}
package com.sap.sailing.selenium.test.adminconsole.pages;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import com.sap.sailing.selenium.core.BySeleniumId;
import com.sap.sailing.selenium.core.FindBy;
import com.sap.sailing.selenium.test.PageArea;
import com.sap.sailing.selenium.test.gwt.widgets.CellTable;
public class LeaderboardConfigurationPanel extends PageArea {
@FindBy(how = BySeleniumId.class, using = "CreateFlexibleLeaderboardButton")
private WebElement createFlexibleLeaderboardButton;
@FindBy(how = BySeleniumId.class, using = "CreateRegattaLeaderboardButton")
private WebElement createRegattaLeaderboardButton;
@FindBy(how = BySeleniumId.class, using = "AvailableLeaderboardsTable")
private WebElement availableLeaderboardsTable;
protected LeaderboardConfigurationPanel(WebDriver driver, WebElement element) {
super(driver, element);
}
public List<String> getAvailableLeaderboards() {
List<String> leaderboards = new ArrayList<>();
CellTable table = getLeaderboardTable();
List<WebElement> rows = table.getRows();
for(WebElement row : rows) {
WebElement name = row.findElement(By.xpath(".//td/div/a"));
leaderboards.add(name.getText());
}
return leaderboards;
}
public void deleteLeaderboard(String leaderboard) {
CellTable table = getLeaderboardTable();
List<WebElement> rows = table.getRows();
for(WebElement row : rows) {
WebElement name = row.findElement(By.xpath(".//td/div/a"));
if(!leaderboard.equals(name.getText()))
continue;
WebElement removeAction = row.findElement(By.xpath(".//td/div/div[@title='Remove']/img"));
removeAction.click();
this.driver.switchTo().alert().accept();
}
}
public FlexibleLeaderboardCreationDialog startCreatingFlexibleLeaderboard() {
this.createFlexibleLeaderboardButton.click();
// Wait, since we trigger an AJAX-request to get the available events
waitForAjaxRequests();
WebElement dialog = findElementBySeleniumId(this.driver, "CreateFlexibleLeaderboardDialog");
return new FlexibleLeaderboardCreationDialog(this.driver, dialog);
}
private CellTable getLeaderboardTable() {
return new CellTable(this.driver, this.availableLeaderboardsTable);
}
protected void initElements() {
super.initElements();
//this.availableLeaderboardsTable = new CellTable(this.driver, findElementBySeleniumId("AvailableLeaderboardsTable"));
}
}
@@ -1,31 +1,98 @@
package com.sap.sailing.selenium.test.gwt.widgets;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import com.sap.sailing.selenium.test.PageObject;
/**
* <p></p>
*
* @author
* D049941
*/
public class CellTable extends PageObject {
/**
* <p></p>
*
* @param driver
*
* @param element
*
*/
public CellTable(WebDriver driver, WebElement element) {
super(driver, element);
}
@Override
protected void verify() {
// TODO: Verify that the context represents a GWT CellTable
}
}
package com.sap.sailing.selenium.test.gwt.widgets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import com.sap.sailing.selenium.test.PageObject;
/**
* <p></p>
*
* @author
* D049941
*/
public class CellTable extends PageObject {
/**
* <p></p>
*
* @param driver
*
* @param element
*
*/
public CellTable(WebDriver driver, WebElement element) {
super(driver, element);
}
public List<String> getHeaders() {
List<String> headers = new ArrayList<>();
for(WebElement header : findHeaders()) {
headers.add(header.getText());
}
return headers;
}
public void clickHeader(String name) {
for(WebElement header : findHeaders()) {
if(name.equals(header.getText()))
header.click();
}
}
public List<WebElement> getRows() {
List<WebElement> bodies = this.context.findElements(By.tagName("tbody"));
for(WebElement body : bodies) {
if(!body.isDisplayed())
continue;
List<WebElement> rows = body.findElements(By.tagName("tr"));
Iterator<WebElement> iterator = rows.iterator();
while(iterator.hasNext()) {
WebElement row = iterator.next();
if(isRowForLoadingAnimation(row))
iterator.remove();
}
return rows;
}
return Collections.emptyList();
}
@Override
protected void verify() {
// TODO: Verify that the context represents a GWT CellTable
String tagName = ((WebElement) this.context).getTagName();
if(!tagName.equalsIgnoreCase("table"))
throw new IllegalArgumentException("WebElement does not represent a table");
}
private List<WebElement> findHeaders() {
return this.context.findElements(By.tagName("th"));
}
private boolean isRowForLoadingAnimation(WebElement row) {
List<WebElement> images = row.findElements(By.xpath(".//td/div/div/div/img"));
if(images.isEmpty() || images.size() > 1)
return false;
WebElement image = images.get(0);
System.out.println(image.getCssValue("background-image"));
return true;
}
}
@@ -67,15 +67,6 @@
<servlet-name>RCCompetitors</servlet-name>
<url-pattern>/rc/competitors</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RCRegattaRaceStates</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.rc.RegattaRaceStatesJsonGetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RCRegattaRaceStates</servlet-name>
<url-pattern>/rc/regattaRaceStates</url-pattern>
</servlet-mapping>
<!-- RACE COMMITTEE END -->
@@ -106,6 +97,15 @@
<url-pattern>/events</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>EventRaceStatesServlet</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.EventRaceStatesJsonGetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EventRaceStatesServlet</servlet-name>
<url-pattern>/eventRaceStates</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RegattasJsonGetServlet</servlet-name>
<servlet-class>com.sap.sailing.server.gateway.impl.RegattasJsonGetServlet</servlet-class>
@@ -1,4 +1,4 @@
package com.sap.sailing.server.gateway.impl.rc;
package com.sap.sailing.server.gateway.impl;
import java.io.IOException;
import java.util.Calendar;
@@ -32,10 +32,10 @@ import com.sap.sailing.domain.racelog.analyzing.impl.RaceStatusAnalyzer;
import com.sap.sailing.domain.racelog.analyzing.impl.StartTimeFinder;
import com.sap.sailing.server.gateway.AbstractJsonHttpServlet;
public class RegattaRaceStatesJsonGetServlet extends AbstractJsonHttpServlet {
public class EventRaceStatesJsonGetServlet extends AbstractJsonHttpServlet {
private static final long serialVersionUID = -4820965681871902242L;
private final static Logger logger = Logger.getLogger(RegattaRaceStatesJsonGetServlet.class.getName());
private final static Logger logger = Logger.getLogger(EventRaceStatesJsonGetServlet.class.getName());
private static final String PARAM_NAME_EVENTID = "eventId";
private static final String PARAM_NAME_FILTER_BY_COURSEAREA = "filterByCourseArea";