Merge branch 'master' into bug3345

# Conflicts:
#	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java
#	java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/home/solutions/SailingAnalyticsNotes.html
This commit is contained in:
Steffen Schaefer committed 2015-12-04 11:27:47 +01:00
commit 05aa98d84c
112 files changed
+7838 -7403

No files matched your search

@@ -94,8 +94,8 @@ public class TracTrac {
new MillisecondsTimePoint(record.getTrackingStartTime().asMillis()),
new MillisecondsTimePoint(record.getTrackingEndTime().asMillis()),
raceLogStore, regattaLogStore,
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, /* simulateWithStartTimeNow */
false, /*useTracTracMarkPassings*/ false,
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, /* offsetToStartTimeOfSimulatedRace */
null, /*useTracTracMarkPassings*/ false,
/* tracTracUsername */"", /* tracTracPassword */"", record.getRaceStatus(),
record.getRaceVisibility());
} else {
@@ -11,19 +11,6 @@
<artifactId>com.sap.sailing.dashboards.gwt</artifactId>
<packaging>eclipse-plugin</packaging>
<repositories>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
+40 -40
View File
@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -21,7 +21,7 @@ public abstract class AbstractSpeedImpl implements Speed {
@Override
public Duration getDuration(Distance distance) {
return new MillisecondsDurationImpl((long) (1000 * distance.getMeters() / getMetersPerSecond()));
return distance == null ? null : new MillisecondsDurationImpl((long) (1000 * distance.getMeters() / getMetersPerSecond()));
}
@Override
@@ -14,7 +14,8 @@ Require-Bundle: com.sap.sse.mongodb,
com.sap.sailing.server.gateway.serialization,
com.sap.sse.common,
com.sap.sse,
com.sap.sailing.server.gateway.serialization.shared.android
com.sap.sailing.server.gateway.serialization.shared.android,
com.sap.sse.shared.android
Export-Package: com.sap.sailing.domain.persistence,
com.sap.sailing.domain.persistence.impl;
x-friends:="com.sap.sailing.domain.persistence.test,
@@ -224,11 +224,11 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.common.impl.TimeRangeImpl;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class DomainObjectFactoryImpl implements DomainObjectFactory {
private static final Logger logger = Logger.getLogger(DomainObjectFactoryImpl.class.getName());
@@ -1,39 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.domain.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -1,98 +1,98 @@
package com.sap.sailing.domain.base;
import java.net.URL;
import java.util.Map;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sse.common.Named;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.common.media.WithMedia;
/**
* Base interface for an Event consisting of all static information, which might be shared
* by the server and an Android application.
*/
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
void setDescription(String description);
/**
* @return a non-<code>null</code> venue for this event
*/
Venue getVenue();
/**
* @return the start date of the event
*/
TimePoint getStartDate();
void setStartDate(TimePoint startDate);
/**
* @return the end date of the event
*/
TimePoint getEndDate();
void setEndDate(TimePoint startDate);
boolean isPublic();
void setPublic(boolean isPublic);
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to image resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getImageURLs();
/**
* @deprecated
* An event may have zero or more sponsors, each of which usually want to see their logo on the web page.
*
* @return the sponsors' logos; always non-<code>null</code> but possibly empty
*/
Iterable<URL> getSponsorImageURLs();
/**
* @deprecated
* An optional logo image; may return <code>null</code>.
*/
URL getLogoImageURL();
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to video resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getVideoURLs();
/**
* @return the URL of the event's official web site, or <code>null</code> if such a site does not exist or its URL
* is not known
*/
URL getOfficialWebsiteURL();
void setOfficialWebsiteURL(URL officialWebsiteURL);
/**
* @return the URL of an external web site containing sailor related information like protests, official results, etc.
* or <code>null</code> if such a site does not exist or its URL is not known.
*/
URL getSailorsInfoWebsiteURL();
void setSailorsInfoWebsiteURL(URL sailorsInfoWebsiteURL);
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
/**
* Sets and converts all event images and videos from the old URL based format to the new richer format
* */
boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs, URL logoImageURL, Map<URL, ImageSize> imageSizes);
}
package com.sap.sailing.domain.base;
import java.net.URL;
import java.util.Map;
import com.sap.sailing.domain.common.Renamable;
import com.sap.sse.common.Named;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.shared.media.WithMedia;
/**
* Base interface for an Event consisting of all static information, which might be shared
* by the server and an Android application.
*/
public interface EventBase extends Named, WithDescription, Renamable, WithID, WithMedia {
void setDescription(String description);
/**
* @return a non-<code>null</code> venue for this event
*/
Venue getVenue();
/**
* @return the start date of the event
*/
TimePoint getStartDate();
void setStartDate(TimePoint startDate);
/**
* @return the end date of the event
*/
TimePoint getEndDate();
void setEndDate(TimePoint startDate);
boolean isPublic();
void setPublic(boolean isPublic);
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to image resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getImageURLs();
/**
* @deprecated
* An event may have zero or more sponsors, each of which usually want to see their logo on the web page.
*
* @return the sponsors' logos; always non-<code>null</code> but possibly empty
*/
Iterable<URL> getSponsorImageURLs();
/**
* @deprecated
* An optional logo image; may return <code>null</code>.
*/
URL getLogoImageURL();
/**
* @deprecated
* Returns a non-<code>null</code> live but unmodifiable collection of URLs pointing to video resources that can be
* used to represent the event, e.g., on a web page.
*
* @return a non-<code>null</code> value which may be empty
*/
Iterable<URL> getVideoURLs();
/**
* @return the URL of the event's official web site, or <code>null</code> if such a site does not exist or its URL
* is not known
*/
URL getOfficialWebsiteURL();
void setOfficialWebsiteURL(URL officialWebsiteURL);
/**
* @return the URL of an external web site containing sailor related information like protests, official results, etc.
* or <code>null</code> if such a site does not exist or its URL is not known.
*/
URL getSailorsInfoWebsiteURL();
void setSailorsInfoWebsiteURL(URL sailorsInfoWebsiteURL);
Iterable<? extends LeaderboardGroupBase> getLeaderboardGroups();
/**
* Sets and converts all event images and videos from the old URL based format to the new richer format
* */
boolean setMediaURLs(Iterable<URL> imageURLs, Iterable<URL> sponsorImageURLs, Iterable<URL> videoURLs, URL logoImageURL, Map<URL, ImageSize> imageSizes);
}
@@ -15,15 +15,15 @@ import com.sap.sailing.domain.base.Venue;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.common.media.MediaDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.common.media.MediaUtils;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.MediaDescriptor;
import com.sap.sse.shared.media.MediaUtils;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public abstract class EventBaseImpl implements EventBase {
private static final long serialVersionUID = -5749964088848611074L;
@@ -60,7 +60,7 @@ public class MultipleClassesInRegattaTest {
httpAndHost
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=cce678c8-97e6-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
@@ -71,7 +71,7 @@ public class MultipleClassesInRegattaTest {
httpAndHost
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=11290bd6-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
@@ -82,7 +82,7 @@ public class MultipleClassesInRegattaTest {
httpAndHost
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=39635b24-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
@@ -93,7 +93,7 @@ public class MultipleClassesInRegattaTest {
httpAndHost
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=04498426-7dfd-11e0-8236-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
@@ -67,7 +67,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
+ TracTracConnectionConstants.PORT_STORED), new URI(
"http://tracms.traclive.dk/update_course"),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l,
/* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
/* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "", "",
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
@@ -44,6 +44,7 @@ import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl;
import com.sap.sailing.domain.tractracadapter.impl.RaceCourseReceiver;
import com.sap.sailing.domain.tractracadapter.impl.Simulator;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.tractrac.model.lib.api.data.IPosition;
@@ -95,7 +96,6 @@ public interface DomainFactory {
* Fetch a race definition previously created by a call to {@link #getOrCreateRaceDefinitionAndTrackedRace}. If no such
* race definition was created so far, the call blocks until such a definition is provided by a call to
* {@link #getOrCreateRaceDefinitionAndTrackedRace}.
* @param raceId TODO
*/
RaceDefinition getAndWaitForRaceDefinition(UUID raceId);
@@ -105,7 +105,6 @@ public interface DomainFactory {
* A new {@link com.sap.sailing.domain.base.Regatta} is created if no event by
* an equal name with a boat class with an equal name as the <code>event</code>'s
* boat class exists yet.
* @param trackedRegattaRegistry TODO
*/
com.sap.sailing.domain.base.Regatta getOrCreateDefaultRegatta(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
IRace race, TrackedRegattaRegistry trackedRegattaRegistry);
@@ -134,27 +133,30 @@ public interface DomainFactory {
* if <code>null</code>, all stored data until the "end of time" will be loaded that the event has
* to provide, particularly for the mark positions which are stored per event, not per race; otherwise,
* particularly the mark position loading will be constrained to this end time.
* @param offsetToStartTimeOfSimulatedRace
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
* @param windStore
* Provides the capability to obtain the {@link WindTrack}s for the different wind sources. A trivial
* implementation is {@link EmptyWindStore} which simply provides new, empty tracks. This is always
* available but loses track of the wind, e.g., during server restarts.
* @param raceLogResolver TODO
*/
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException;
/**
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)}, only that
* a predefined {@link Regatta} is used to hold the resulting races.
* @param raceLogResolver TODO
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)},
* only that a predefined {@link Regatta} is used to hold the resulting races.
*
* @param offsetToStartTimeOfSimulatedRace
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
*/
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
@@ -262,9 +264,13 @@ public interface DomainFactory {
Util.Pair<Iterable<com.sap.sailing.domain.base.Competitor>, BoatClass> getCompetitorsAndDominantBoatClass(IRace race);
/**
* @param offsetToStartTimeOfSimulatedRace
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
*/
RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility);
/**
* Removes all knowledge about <code>tractracRace</code> which includes removing it from the race cache, from the
@@ -17,6 +17,8 @@ import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tractracadapter.impl.Simulator;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -65,12 +67,13 @@ public interface TracTracAdapter {
* created, with a single default series and a single default fleet. If a valid {@link RegattaIdentifier}
* is specified, a regatta lookup is performed with that identifier; if the regatta is found, it is used
* to add the races to. Otherwise, a default regatta as described above will be created and used.
* @param raceStatus
* @param offsetToStartTimeOfSimulatedRace
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
*/
RaceHandle addTracTracRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, URL paramURL,
URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint trackingStartTime,
TimePoint trackingEndTime, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
long timeoutForReceivingRaceDefinitionInMilliseconds, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm,
long timeoutForReceivingRaceDefinitionInMilliseconds, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
@@ -74,6 +74,7 @@ import com.sap.sailing.domain.tractracadapter.ReceiverType;
import com.sap.sailing.domain.tractracadapter.TracTracConfiguration;
import com.sap.sailing.domain.tractracadapter.TracTracControlPoint;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
@@ -652,27 +653,27 @@ public class DomainFactoryImpl implements DomainFactory {
@Override
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException,
URISyntaxException, CreateModelException, SubscriberInitializationException {
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
}
@Override
public RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
SubscriberInitializationException {
return new TracTracRaceTrackerImpl(regatta, this, paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore,
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver);
}
@@ -690,11 +691,11 @@ public class DomainFactoryImpl implements DomainFactory {
@Override
public RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility) {
return new RaceTrackingConnectivityParametersImpl(paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore,
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
regattaLogStore, this, tracTracUsername, tracTracPassword, raceStatus, raceVisibility);
}
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.tractrac.model.lib.api.event.CreateModelException;
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
@@ -31,7 +32,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
private final RegattaLogStore regattaLogStore;
private final DomainFactory domainFactory;
private final long delayToLiveInMillis;
private final boolean simulateWithStartTimeNow;
private final Duration offsetToStartTimeOfSimulatedRace;
private final String tracTracUsername;
private final String tracTracPassword;
private final String raceStatus;
@@ -40,7 +41,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
public RaceTrackingConnectivityParametersImpl(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
DomainFactory domainFactory, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility) {
super();
@@ -52,7 +53,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
this.endOfTracking = endOfTracking;
this.delayToLiveInMillis = delayToLiveInMillis;
this.domainFactory = domainFactory;
this.simulateWithStartTimeNow = simulateWithStartTimeNow;
this.offsetToStartTimeOfSimulatedRace = offsetToStartTimeOfSimulatedRace;
this.raceLogStore = raceLogStore;
this.regattaLogStore = regattaLogStore;
this.tracTracUsername = tracTracUsername;
@@ -67,7 +68,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException, URISyntaxException,
CreateModelException, SubscriberInitializationException {
RaceTracker tracker = domainFactory.createRaceTracker(paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore,
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver);
return tracker;
@@ -77,7 +78,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
WindStore windStore, GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws Exception {
RaceTracker tracker = domainFactory.createRaceTracker(regatta, paramURL, liveURI, storedURI,
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm,
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm,
raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
raceVisibility, trackedRegattaRegistry, raceLogResolver);
return tracker;
@@ -4,7 +4,6 @@ import java.util.logging.Logger;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -57,13 +56,13 @@ public class RawPositionReceiver extends AbstractReceiverWithQueue<IRaceCompetit
IRace race = event.getA().getRace();
DynamicTrackedRace trackedRace = getTrackedRace(race);
if (trackedRace != null) {
GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
if (getSimulator() != null) {
fix = new GPSFixMovingImpl(fix.getPosition(), getSimulator().delay(
fix.getTimePoint()), fix.getSpeed());
}
final GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
trackedRace.recordFix(competitor, fix);
if (getSimulator() != null) {
getSimulator().scheduleCompetitorPosition(competitor, fix);
} else {
trackedRace.recordFix(competitor, fix);
}
} else {
logger.warning("Couldn't find tracked race for race " + race.getName()
+ ". Dropping raw position event " + event);
@@ -24,7 +24,9 @@ import com.sap.sailing.domain.tracking.WindStore;
import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class Simulator {
@@ -33,13 +35,15 @@ public class Simulator {
private DynamicTrackedRace trackedRace;
private final WindStore windStore;
private boolean stopped;
private long advanceInMillis = -1;
private Duration advanceInMillis = Duration.NULL.minus(1);
private Timer timer = new Timer("Timer for TracTrac Simulator");
private final Duration offsetToStart;
public Simulator(WindStore windStore) {
public Simulator(WindStore windStore, Duration offsetToStart) {
super();
assert windStore != null;
this.windStore = windStore;
this.offsetToStart = offsetToStart;
}
/**
@@ -69,7 +73,7 @@ public class Simulator {
/**
* This is what everybody is waiting for :-). Notifies all waiters.
*/
public synchronized void setAdvanceInMillis(long advanceInMillis) {
public synchronized void setAdvanceInMillis(Duration advanceInMillis) {
this.advanceInMillis = advanceInMillis;
notifyAll();
}
@@ -114,7 +118,7 @@ public class Simulator {
* Waits until {@link #advanceInMillis} is set to something not equal to -1 which is its initial value. Unblocked by
* {@link #setAdvanceInMillis(long)}.
*/
private synchronized long getAdvanceInMillis() {
private synchronized Duration getAdvance() {
while (!isAdvanceInMillisSet()) {
try {
wait(2000); // wait for two seconds, then re-evaluate whether there is a start time
@@ -125,6 +129,16 @@ public class Simulator {
}
return advanceInMillis;
}
private Duration getOffsetToStart() {
final Duration result;
if (offsetToStart != null) {
result = offsetToStart;
} else {
result = Duration.NULL;
}
return result;
}
/**
* Transforms <code>timed</code>'s time point according to this simulator's delay and waits roughly until this time
@@ -157,12 +171,12 @@ public class Simulator {
* Like {@link #delay}, only that it doesn't wait until <code>timePoint</code> is reached in wall time.
*/
public TimePoint advance(TimePoint timePoint) {
return new MillisecondsTimePoint(timePoint.asMillis()+getAdvanceInMillis());
return timePoint.plus(getAdvance());
}
/**
* If {@link #advanceInMillis} is already set to a non-negative value, it is left alone, and
* {@link #delay(TimePoint)} is called. Otherwise, <code>time</code> is taken to be the original start time of the
* {@link #advance(TimePoint)} is called. Otherwise, <code>time</code> is taken to be the original start time of the
* race which is then used to compute {@link #advanceInMillis} such that
* <code>time.asMillis() + advanceInMillis == System.currentTimeMillis()</code>.
*/
@@ -183,13 +197,13 @@ public class Simulator {
if (isAdvanceInMillisSet()) {
return advance(time);
} else {
setAdvanceInMillis(System.currentTimeMillis() - time.asMillis());
setAdvanceInMillis(new MillisecondsDurationImpl(MillisecondsTimePoint.now().minus(time.asMillis()).plus(getOffsetToStart()).asMillis()));
return advance(time);
}
}
private boolean isAdvanceInMillisSet() {
return advanceInMillis != -1;
return !advanceInMillis.equals(Duration.NULL.minus(1));
}
/**
@@ -238,21 +252,35 @@ public class Simulator {
// deliver an empty list now
trackedRace.updateMarkPassings(competitor, markPassings);
}
}
public void scheduleCompetitorPosition(final Competitor competitor, GPSFixMoving competitorFix) {
final RecordGPSFix<Competitor> recorder = (c, f)->trackedRace.recordFix(c, f);
scheduleFixRecording(competitor, competitorFix, recorder);
}
@FunctionalInterface
private static interface RecordGPSFix<T> {
void recordFix(T objectForFix, GPSFixMoving fix);
}
public void scheduleMarkPosition(final Mark mark, GPSFixMoving markFix) {
final TimePoint transformedTimepoint = advance(markFix.getTimePoint());
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(markFix.getPosition(), transformedTimepoint, markFix.getSpeed());
final RecordGPSFix<Mark> recorder = (m, f)->trackedRace.recordFix(mark, f);
scheduleFixRecording(mark, markFix, recorder);
}
private <T> void scheduleFixRecording(final T object, GPSFixMoving fix, final RecordGPSFix<T> recorder) {
final TimePoint transformedTimepoint = advance(fix.getTimePoint());
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed());
long waitTime = getWaitTimeInMillisUntil(transformedMarkFix.getTimePoint());
if (waitTime <= 0) {
trackedRace.recordFix(mark, transformedMarkFix);
recorder.recordFix(object, transformedMarkFix);
} else {
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
trackedRace.recordFix(mark, transformedMarkFix);
recorder.recordFix(object, transformedMarkFix);
} catch (Exception e) {
logger.throwing(Simulator.class.getName(), "scheduleMarkPosition", e);
}
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.tractracadapter.JSONService;
import com.sap.sailing.domain.tractracadapter.RaceRecord;
import com.sap.sailing.domain.tractracadapter.TracTracAdapter;
import com.sap.sailing.domain.tractracadapter.TracTracConfiguration;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -56,7 +57,7 @@ public class TracTracAdapterImpl implements TracTracAdapter {
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
courseDesignUpdateURI,
/* startOfTracking */null,
/* endOfTracking */null, delayToLiveInMillis, /* simulateWithStartTimeNow */false, /* ignoreTracTracMarkPassings */ false,
/* endOfTracking */null, delayToLiveInMillis, /* offsetToStartTimeOfSimulatedRace */null, /* ignoreTracTracMarkPassings */ false,
raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility),
timeoutInMilliseconds);
}
@@ -65,13 +66,13 @@ public class TracTracAdapterImpl implements TracTracAdapter {
public RaceHandle addTracTracRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, URL paramURL,
URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword, String raceStatus,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword, String raceStatus,
String raceVisibility) throws Exception {
return trackerManager.addRace(
regattaToAddTo,
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword,
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword,
raceStatus, raceVisibility), timeoutInMilliseconds);
}
@@ -49,6 +49,7 @@ import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.Receiver;
import com.sap.sailing.domain.tractracadapter.TracTracConnectionConstants;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.tractrac.model.lib.api.ModelLocator;
@@ -253,26 +254,26 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
*/
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException,
SubscriberInitializationException {
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), domainFactory, paramURL, liveURI,
storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
}
private TracTracRaceTrackerImpl(IRace tractracRace, DomainFactory domainFactory, URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
FileNotFoundException, SubscriberInitializationException {
this(tractracRace, null, domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
}
@@ -284,14 +285,14 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
*/
protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException,
MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), regatta, domainFactory, paramURL,
liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
simulateWithStartTimeNow, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
}
@@ -300,15 +301,15 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
* @param regatta
* if <code>null</code>, then <code>domainFactory.getOrCreateRegatta(tractracEvent)</code> will be used
* to obtain a default regatta
* @param simulateWithStartTimeNow
* if <code>true</code>, the connector will adjust the time stamps of all events received such that the
* @param offsetToStartTimeOfSimulatedRace
* if not <code>null</code>, the connector will adjust the time stamps of all events received such that the
* first mark passing for the first waypoint will be set to "now." It will delay the forwarding of all
* events received such that they seem to be sent in "real-time." So, more or less the time points
* events received such that they seem to be sent in "real-time" + <code>offsetToStartTimeOfSimulatedRace</code> So, more or less the time points
* attached to the events sent to the receivers will again approximate the wall time.
*/
private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory,
URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm,
TimePoint endOfTracking, long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore,
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility,
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
@@ -323,8 +324,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
this.gpsFixStore = gpsFixStore;
this.domainFactory = domainFactory;
this.lastProgressPerID = new HashMap<>();
if (simulateWithStartTimeNow) {
simulator = new Simulator(windStore);
if (offsetToStartTimeOfSimulatedRace != null) {
simulator = new Simulator(windStore, offsetToStartTimeOfSimulatedRace);
// don't write the transformed wind fixes into the DB again... see also bug 1974
this.windStore = EmptyWindStore.INSTANCE;
} else {
@@ -43,4 +43,6 @@ public interface Course extends CourseBase {
void update(Iterable<Util.Pair<ControlPoint, PassingInstruction>> newControlPoints, DomainFactory baseDomainFactory) throws PatchFailedException;
int getNumberOfWaypoints();
Leg getLeg(int zeroBasedIndexOfWaypoint);
}
@@ -246,6 +246,11 @@ public class CourseImpl extends NamedImpl implements Course {
return waypoints.size();
}
@Override
public Leg getLeg(int zeroBasedIndexOfWaypoint) {
return legs.get(zeroBasedIndexOfWaypoint);
}
@Override
public String toString() {
lockForRead();
@@ -13,7 +13,6 @@ import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
@@ -154,6 +153,7 @@ import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.concurrent.LockUtil;
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
import com.sap.sse.util.IdentityWrapper;
import com.sap.sse.util.SmartFutureCache;
import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
@@ -183,7 +183,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
* By default, all wind sources are used, none are excluded. However, e.g., for performance reasons, particular wind
* sources such as the track-based estimation wind source, may be excluded by adding them to this set.
*/
private final Set<WindSource> windSourcesToExclude;
private final ConcurrentHashMap<WindSource, TrackedRaceImpl> windSourcesToExclude;
/**
* Keeps the oldest timestamp that is fed into this tracked race, either from a boat fix, a mark fix, a race
@@ -269,7 +269,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
*/
private transient SmartFutureCache<Competitor, com.sap.sse.common.Util.Triple<TimePoint, TimePoint, List<Maneuver>>, EmptyUpdateInterval> maneuverCache;
private transient Map<TimePoint, Future<Wind>> directionFromStartToNextMarkCache;
private transient ConcurrentHashMap<TimePoint, Future<Wind>> directionFromStartToNextMarkCache;
protected final MarkPassingCalculator markPassingCalculator;
@@ -354,7 +354,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
*/
private final NamedReentrantReadWriteLock loadingFromGPSFixStoreLock;
private final Map<Iterable<MarkPassing>, NamedReentrantReadWriteLock> locksForMarkPassings;
private final ConcurrentHashMap<IdentityWrapper<Iterable<MarkPassing>>, NamedReentrantReadWriteLock> locksForMarkPassings;
/**
* Caches wind requests for a few seconds to accelerate access in live mode
@@ -412,7 +412,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
rankingMetric = rankingMetricConstructor.apply(this);
raceStates = new WeakHashMap<>();
shortTimeWindCache = new ShortTimeWindCache(this, millisecondsOverWhichToAverageWind / 2);
locksForMarkPassings = new IdentityHashMap<>();
locksForMarkPassings = new ConcurrentHashMap<IdentityWrapper<Iterable<MarkPassing>>, NamedReentrantReadWriteLock>();
attachedRaceLogs = new ConcurrentHashMap<>();
attachedRegattaLogs = new ConcurrentHashMap<>();
attachedRaceExecutionOrderProviders = new ConcurrentHashMap<>();
@@ -424,8 +424,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
+ race.getName(), /* fair */ false);
this.cacheInvalidationTimerLock = new Object();
this.updateCount = 0;
this.windSourcesToExclude = new HashSet<WindSource>();
this.directionFromStartToNextMarkCache = new HashMap<TimePoint, Future<Wind>>();
this.windSourcesToExclude = new ConcurrentHashMap<>();
this.directionFromStartToNextMarkCache = new ConcurrentHashMap<TimePoint, Future<Wind>>();
this.millisecondsOverWhichToAverageSpeed = millisecondsOverWhichToAverageSpeed;
this.delayToLiveInMillis = delayToLiveInMillis;
this.startToNextMarkCacheInvalidationListeners = new ConcurrentHashMap<Mark, TrackedRaceImpl.StartToNextMarkCacheInvalidationListener>();
@@ -624,7 +624,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
gpsFixStore = EmptyGPSFixStore.INSTANCE;
competitorRankings = createCompetitorRankingsCache();
competitorRankingsLocks = createCompetitorRankingsLockMap();
directionFromStartToNextMarkCache = new HashMap<TimePoint, Future<Wind>>();
directionFromStartToNextMarkCache = new ConcurrentHashMap<>();
crossTrackErrorCache = new CrossTrackErrorCache(this);
crossTrackErrorCache.invalidate();
maneuverCache = createManeuverCache();
@@ -1146,11 +1146,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
int indexOfWaypoint = getRace().getCourse().getIndexOfWaypoint(startOfLeg);
if (indexOfWaypoint == -1) {
throw new IllegalArgumentException("Waypoint " + startOfLeg + " not found in " + getRace().getCourse());
} else if (indexOfWaypoint == Util.size(getRace().getCourse().getWaypoints()) - 1) {
} else if (indexOfWaypoint == getRace().getCourse().getNumberOfWaypoints() - 1) {
throw new IllegalArgumentException("Waypoint " + startOfLeg + " isn't start of any leg in "
+ getRace().getCourse());
}
return trackedLegs.get(race.getCourse().getLegs().get(indexOfWaypoint));
return trackedLegs.get(race.getCourse().getLeg(indexOfWaypoint));
} finally {
getRace().getCourse().unlockAfterRead();
}
@@ -1679,24 +1679,20 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
@Override
public Set<WindSource> getWindSourcesToExclude() {
synchronized (windSourcesToExclude) {
return Collections.unmodifiableSet(windSourcesToExclude);
}
return Collections.unmodifiableSet(windSourcesToExclude.keySet());
}
@Override
public void setWindSourcesToExclude(Iterable<? extends WindSource> windSourcesToExclude) {
Set<WindSource> old = new HashSet<>(this.windSourcesToExclude);
synchronized (this.windSourcesToExclude) {
LockUtil.lockForRead(getSerializationLock());
try {
this.windSourcesToExclude.clear();
for (WindSource windSourceToExclude : windSourcesToExclude) {
this.windSourcesToExclude.add(windSourceToExclude);
}
} finally {
LockUtil.unlockAfterRead(getSerializationLock());
Set<WindSource> old = new HashSet<>(getWindSourcesToExclude());
LockUtil.lockForRead(getSerializationLock());
try {
this.windSourcesToExclude.clear();
for (WindSource windSourceToExclude : windSourcesToExclude) {
this.windSourcesToExclude.put(windSourceToExclude, this);
}
} finally {
LockUtil.unlockAfterRead(getSerializationLock());
}
if (!old.equals(this.windSourcesToExclude)) {
clearAllCachesExceptManeuvers();
@@ -1742,30 +1738,33 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
public Wind getDirectionFromStartToNextMark(final TimePoint at) {
Future<Wind> future;
FutureTask<Wind> newFuture = null;
synchronized (directionFromStartToNextMarkCache) {
future = directionFromStartToNextMarkCache.get(at);
if (future == null) {
newFuture = new FutureTask<Wind>(new Callable<Wind>() {
@Override
public Wind call() {
Wind result;
Leg firstLeg = getRace().getCourse().getFirstLeg();
if (firstLeg != null) {
Position firstLegEnd = getApproximatePosition(firstLeg.getTo(), at);
Position firstLegStart = getApproximatePosition(firstLeg.getFrom(), at);
if (firstLegStart != null && firstLegEnd != null) {
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(0.0,
firstLegEnd.getBearingGreatCircle(firstLegStart)));
future = directionFromStartToNextMarkCache.get(at);
if (future == null) {
synchronized (directionFromStartToNextMarkCache) {
future = directionFromStartToNextMarkCache.get(at);
if (future == null) {
newFuture = new FutureTask<Wind>(new Callable<Wind>() {
@Override
public Wind call() {
Wind result;
Leg firstLeg = getRace().getCourse().getFirstLeg();
if (firstLeg != null) {
Position firstLegEnd = getApproximatePosition(firstLeg.getTo(), at);
Position firstLegStart = getApproximatePosition(firstLeg.getFrom(), at);
if (firstLegStart != null && firstLegEnd != null) {
result = new WindImpl(firstLegStart, at, new KnotSpeedWithBearingImpl(0.0,
firstLegEnd.getBearingGreatCircle(firstLegStart)));
} else {
result = null;
}
} else {
result = null;
}
} else {
result = null;
return result;
}
return result;
}
});
directionFromStartToNextMarkCache.put(at, newFuture);
});
directionFromStartToNextMarkCache.put(at, newFuture);
}
}
}
if (newFuture != null) {
@@ -2062,15 +2061,19 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
protected NamedReentrantReadWriteLock getMarkPassingsLock(Iterable<MarkPassing> markPassings) {
synchronized (locksForMarkPassings) {
NamedReentrantReadWriteLock lock = locksForMarkPassings.get(markPassings);
if (lock == null) {
lock = new NamedReentrantReadWriteLock("mark passings lock for tracked race " + getRace().getName(), /* fair */
false);
locksForMarkPassings.put(markPassings, lock);
final IdentityWrapper<Iterable<MarkPassing>> markPassingsIdentity = new IdentityWrapper<>(markPassings);
NamedReentrantReadWriteLock lock = locksForMarkPassings.get(markPassingsIdentity);
if (lock == null) {
synchronized (locksForMarkPassings) {
lock = locksForMarkPassings.get(markPassingsIdentity);
if (lock == null) {
lock = new NamedReentrantReadWriteLock(
"mark passings lock for tracked race " + getRace().getName(), /* fair */false);
locksForMarkPassings.put(markPassingsIdentity, lock);
}
}
return lock;
}
return lock;
}
private void updateStartToNextMarkCacheInvalidationCacheListenersAfterWaypointRemoved(int zeroBasedIndex,
@@ -50,6 +50,7 @@
<plugin id="com.sap.sailing.monitoring" autoStart="true" startLevel="6" />
<plugin id="com.sap.sailing.news" autoStart="true" startLevel="3" />
<plugin id="com.sap.sailing.polars" autoStart="true" startLevel="4" />
<plugin id="com.sap.sailing.polars.datamining" autoStart="true" startLevel="4" />
<plugin id="com.sap.sailing.resultimport" autoStart="true" startLevel="3" />
<plugin id="com.sap.sailing.sailwave.resultimport" autoStart="true" startLevel="3" />
<plugin id="com.sap.sailing.server" autoStart="true" startLevel="4" />
@@ -95,7 +95,7 @@ public class GwtTestCaseColumnToggling extends GWTTestCase {
+ TracTracConnectionConstants.PORT_TUNNEL_STORED : "tcp://" + TracTracConnectionConstants.HOST_NAME
+ ":" + TracTracConnectionConstants.PORT_STORED,
COURSE_DESIGN_UPDATE_URI,
false, false, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings */ false, TRACTRAC_USERNAME, TRACTRAC_PASSWORD, new AsyncCallback<Void>() {
false, false, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings */ false, TRACTRAC_USERNAME, TRACTRAC_PASSWORD, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
@@ -49,9 +49,10 @@ Require-Bundle: com.sap.sailing.domain,
org.apache.shiro.core;bundle-version="1.2.2",
com.sap.sse.gwt.theme,
com.sap.sailing.news,
com.sap.sailing.polars.datamining.shared;bundle-version="1.0.0",
com.sap.sailing.polars.datamining.shared,
com.sap.sailing.polars.datamining,
com.sap.sse.datamining.annotations;bundle-version="1.0.0"
com.sap.sse.datamining.annotations,
com.sap.sse.shared.android
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
Bundle-ActivationPolicy: lazy
Import-Package: javax.servlet;version="3.1.0",
@@ -17,7 +17,7 @@
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
</listAttribute>
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
@@ -73,7 +73,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/EmbeddedMapAndWindChart com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /gwt/AutoPlay.html com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
</launchConfiguration>
@@ -16,7 +16,7 @@
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
@@ -70,7 +70,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -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/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -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/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /gwt/AutoPlay.html com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
-13
View File
@@ -11,19 +11,6 @@
<artifactId>com.sap.sailing.gwt.ui</artifactId>
<packaging>eclipse-plugin</packaging>
<repositories>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<!-- The following dependency needs re-declaration with the desired version
because gwt-maps-api declares it with no version specifier which may be resolved
@@ -22,8 +22,8 @@ import com.sap.sailing.gwt.home.server.EventActionUtil;
import com.sap.sailing.gwt.home.server.LeaderboardContext;
import com.sap.sailing.gwt.home.server.EventActionUtil.LeaderboardCallback;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.shared.media.ImageDescriptor;
public class GetEventViewAction implements SailingAction<EventViewDTO>, IsClientCacheable {
private static final Logger logger = Logger.getLogger(GetEventViewAction.class.getName());
@@ -20,7 +20,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class GetEventOverviewStageAction implements SailingAction<ResultWithTTL<EventOverviewStageDTO>>, IsClientCacheable {
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.home.communication.event.news;
import java.util.Date;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -18,6 +19,7 @@ public class RaceCompetitorNewsEntryDTO extends AbstractRaceNewsEntryDTO {
private RaceCompetitorNewsEntryDTO() {
}
@GwtIncompatible
public RaceCompetitorNewsEntryDTO(String leaderboardName, String leaderboardGroupName,
RegattaAndRaceIdentifier regattaAndRaceIdentifier, String raceTitle, String boatClass, Date timestamp,
String competitorName, Type type) {
@@ -16,8 +16,8 @@ import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
import com.sap.sailing.gwt.home.communication.event.EventMetadataDTO;
import com.sap.sailing.gwt.home.communication.fakeseries.EventSeriesViewDTO.EventSeriesState;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.shared.media.ImageDescriptor;
public class GetEventSeriesViewAction implements SailingAction<EventSeriesViewDTO>, IsClientCacheable {
@@ -11,9 +11,9 @@ import com.sap.sailing.gwt.home.communication.SailingDispatchContext;
import com.sap.sailing.gwt.home.communication.event.EventReferenceDTO;
import com.sap.sailing.gwt.server.HomeServiceUtil;
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class GetMediaForEventAction implements SailingAction<MediaDTO>, IsClientCacheable {
@@ -22,9 +22,9 @@ import com.sap.sailing.gwt.server.RecentEventsCalculator;
import com.sap.sailing.gwt.ui.shared.media.MediaConstants;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class GetStartViewAction implements SailingAction<StartViewDTO>, IsClientCacheable {
private static final int MAX_RECENT_EVENTS = 3;
@@ -44,12 +44,12 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MediaDescriptor;
import com.sap.sse.common.media.MediaTagConstants;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.gwt.client.media.ImageDTO;
import com.sap.sse.gwt.client.media.VideoDTO;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.MediaDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public final class HomeServiceUtil {
public interface EventVisitor {
@@ -36,26 +36,31 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
private boolean editable;
private String boatClass;
protected String leaderboardName;
/**
* @param boatClass
* The <code>boatClass</code> parameter describes the default shown boat class for new competitors. The <code>boatClass</code> parameter is <code>null</code>,
* if you want to edit a competitor or there is no boat class for the new competitor.
* The <code>boatClass</code> parameter describes the default shown boat class for new competitors. The
* <code>boatClass</code> parameter is <code>null</code>, if you want to edit a competitor or there is no
* boat class for the new competitor.
*/
public AbstractCompetitorRegistrationsDialog(final SailingServiceAsync sailingService,
final StringMessages stringMessages, final ErrorReporter errorReporter, boolean editable,
DialogCallback<Set<CompetitorDTO>> callback, String boatClass) {
super(stringMessages.registerCompetitors(), /*messsage*/ null, stringMessages.save(), stringMessages.cancel(), /*validator*/ null, callback);
DialogCallback<Set<CompetitorDTO>> callback, String leaderboardName, String boatClass) {
super(stringMessages.registerCompetitors(), /* messsage */null, stringMessages.save(), stringMessages.cancel(), /* validator */
null, callback);
this.stringMessages = stringMessages;
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.errorReporter = errorReporter;
this.editable = editable;
this.leaderboardName = leaderboardName;
this.boatClass = boatClass;
}
@Override
protected Widget getAdditionalWidget() {
FlowPanel mainPanel = new FlowPanel();
Button addCompetitorButton = new Button(stringMessages.add(stringMessages.competitor()));
addCompetitorButton.addClickHandler(new ClickHandler() {
@Override
@@ -63,7 +68,7 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
openAddCompetitorDialog();
}
});
Button editCompetitorButton = new Button(stringMessages.edit(stringMessages.competitor()));
editCompetitorButton.addClickHandler(new ClickHandler() {
@Override
@@ -72,11 +77,25 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
}
});
final Button inviteCompetitorsButton = new Button(stringMessages.inviteSelectedCompetitors());
inviteCompetitorsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
Set<CompetitorDTO> competitors = registeredCompetitorsTable.getSelectionModel().getSelectedSet();
CompetitorInvitationHelper helper = new CompetitorInvitationHelper(sailingService, stringMessages,
errorReporter);
helper.inviteCompetitors(competitors, leaderboardName);
}
});
HorizontalPanel competitorRegistrationPanel = new HorizontalPanel();
CaptionPanel allCompetitorsPanel = new CaptionPanel(stringMessages.competitorPool());
CaptionPanel registeredCompetitorsPanel = new CaptionPanel(stringMessages.registeredCompetitors());
allCompetitorsTable = new CompetitorTableWrapper<>(sailingService, stringMessages, errorReporter, /* multiSelection */ true, /* enablePager */ true);
registeredCompetitorsTable = new CompetitorTableWrapper<>(sailingService, stringMessages, errorReporter, /* multiSelection */ true, /* enablePager */ true);
allCompetitorsTable = new CompetitorTableWrapper<>(sailingService, stringMessages, errorReporter, /* multiSelection */
true, /* enablePager */true);
registeredCompetitorsTable = new CompetitorTableWrapper<>(sailingService, stringMessages, errorReporter, /* multiSelection */
true, /* enablePager */true);
allCompetitorsPanel.add(allCompetitorsTable);
registeredCompetitorsPanel.add(registeredCompetitorsTable);
VerticalPanel movePanel = new VerticalPanel();
@@ -102,16 +121,17 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
competitorRegistrationPanel.add(movePanel);
competitorRegistrationPanel.setCellVerticalAlignment(movePanel, HasVerticalAlignment.ALIGN_MIDDLE);
competitorRegistrationPanel.add(allCompetitorsPanel);
refreshCompetitors();
mainPanel.add(addCompetitorButton);
mainPanel.add(editCompetitorButton);
mainPanel.add(inviteCompetitorsButton);
mainPanel.add(competitorRegistrationPanel);
return mainPanel;
}
void move(CompetitorTableWrapper<?> from, CompetitorTableWrapper<?> to, Collection<CompetitorDTO> toMove) {
if (!toMove.isEmpty()) {
List<CompetitorDTO> newFromList = new ArrayList<>();
@@ -130,7 +150,6 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
move(from, to, from.getSelectionModel().getSelectedSet());
}
private void openAddCompetitorDialog() {
new CompetitorEditDialog(stringMessages, new CompetitorDTOImpl(),
new DataEntryDialog.DialogCallback<CompetitorDTO>() {
@@ -154,37 +173,40 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
}
}, boatClass).show();
}
private void openEditCompetitorDialog() {
//get currently selected competitor
if (registeredCompetitorsTable.getSelectionModel().getSelectedSet().size() != 1){
// get currently selected competitor
if (registeredCompetitorsTable.getSelectionModel().getSelectedSet().size() != 1) {
// show some warning
} else {
final CompetitorDTO competitorToEdit = registeredCompetitorsTable.getSelectionModel().getSelectedSet().iterator().next();
final CompetitorDTO competitorToEdit = registeredCompetitorsTable.getSelectionModel().getSelectedSet()
.iterator().next();
new CompetitorEditDialog(stringMessages, competitorToEdit,
new DataEntryDialog.DialogCallback<CompetitorDTO>() {
@Override
public void ok(CompetitorDTO competitor) {
sailingService.addOrUpdateCompetitor(competitor, new AsyncCallback<CompetitorDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to add competitor: " + caught.getMessage());
public void ok(CompetitorDTO competitor) {
sailingService.addOrUpdateCompetitor(competitor, new AsyncCallback<CompetitorDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to add competitor: " + caught.getMessage());
}
@Override
public void onSuccess(CompetitorDTO updatedCompetitor) {
int editedCompetitorIndex = registeredCompetitorsTable.getDataProvider().getList()
.indexOf(competitorToEdit);
registeredCompetitorsTable.getDataProvider().getList().remove(competitorToEdit);
registeredCompetitorsTable.getDataProvider().getList()
.add(editedCompetitorIndex, updatedCompetitor);
registeredCompetitorsTable.getDataProvider().refresh();
}
});
}
@Override
public void onSuccess(CompetitorDTO updatedCompetitor) {
int editedCompetitorIndex = registeredCompetitorsTable.getDataProvider().getList().indexOf(competitorToEdit);
registeredCompetitorsTable.getDataProvider().getList().remove(competitorToEdit);
registeredCompetitorsTable.getDataProvider().getList().add(editedCompetitorIndex, updatedCompetitor);
registeredCompetitorsTable.getDataProvider().refresh();
public void cancel() {
}
});
}
@Override
public void cancel() {
}
}, /* boatClass */ null).show();
}, /* boatClass */null).show();
}
}
@@ -195,13 +217,13 @@ public abstract class AbstractCompetitorRegistrationsDialog extends DataEntryDia
public void onSuccess(Iterable<CompetitorDTO> result) {
setRegisteredCompetitors();
}
@Override
public void onFailure(Throwable reason) {
}
});
}
protected abstract void setRegisteredCompetitors();
@Override
@@ -40,18 +40,18 @@ public class AddWindFixDialog extends DataEntryDialog<WindDTO> {
if(windDTO.trueWindSpeedInKnots == null) {
errorMessage = stringMessages.pleaseEnterAValue();
} else if(windDTO.trueWindSpeedInKnots != null && (windDTO.trueWindSpeedInKnots < 0.0 || windDTO.trueWindSpeedInKnots > 100.0)) {
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.speedInKnots(), "0", "100");
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.speedInKnots(), 0, 100);
} else if(windDTO.trueWindFromDeg == null){
errorMessage = stringMessages.pleaseEnterAValue();
} else if(windDTO.trueWindFromDeg != null && (windDTO.trueWindFromDeg < 0.0 || windDTO.trueWindFromDeg > 360.0)){
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.fromDeg(), "0", "360");
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.fromDeg(), 0, 360);
} else if(windDTO.measureTimepoint == null) {
errorMessage = stringMessages.pleaseEnterAValue();
} else if(windDTO.position != null) {
if(windDTO.position.getLatDeg() < -90.0 || windDTO.position.getLatDeg() > 90.0){
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.latitude(), "-90", "90");
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.latitude(), -90, 90);
} else if(windDTO.position.getLngDeg() < -180.0 || windDTO.position.getLngDeg() > 180.0){
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.longitude(), "-180", "180");
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.longitude(), -180, 180);
}
}
@@ -0,0 +1,83 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.Set;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
public class CompetitorInvitationHelper {
private StringMessages stringMessages;
private SailingServiceAsync sailingService;
private ErrorReporter errorReporter;
public CompetitorInvitationHelper(SailingServiceAsync sailingService, StringMessages stringMessages, ErrorReporter errorReporter) {
this.stringMessages = stringMessages;
this.sailingService = sailingService;
this.errorReporter = errorReporter;
}
public void inviteCompetitors(Set<CompetitorDTO> competitors, String leaderboardName) {
if (competitors.size() == 0){
Window.alert(stringMessages.selectAtLeastOneCompetitorForInvitation());
} else {
boolean emailProvidedForAll = isEmailProvidedForAll(competitors);
if (emailProvidedForAll) {
openChooseEventDialogAndSendMails(competitors, leaderboardName);
} else {
Window.alert(stringMessages.notAllCompetitorsProvideEmail());
}
}
}
private boolean isEmailProvidedForAll(Iterable<CompetitorDTO> allCompetitors) {
for (CompetitorDTO competitor : allCompetitors) {
if (!competitor.hasEmail()) {
return false;
}
}
return true;
}
private void openChooseEventDialogAndSendMails(final Set<CompetitorDTO> competitors, final String leaderboardName) {
new SelectEventAndHostnameDialog(sailingService, stringMessages, errorReporter, leaderboardName, new DialogCallback<Pair<EventDTO, String>>() {
@Override
public void ok(Pair<EventDTO, String> result) {
sailingService.inviteCompetitorsForTrackingViaEmail(result.getB(), result.getA(), leaderboardName,
competitors, getLocaleInfo(), new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
Window.alert(stringMessages.sendingMailsFailed() + caught.getMessage());
}
@Override
public void onSuccess(Void result) {
Window.alert(stringMessages.sendingMailsSuccessful());
}
});
}
@Override
public void cancel() {
}
}).show();
}
private String getLocaleInfo() {
return LocaleInfo.getCurrentLocale().getLocaleName();
}
}
@@ -8,7 +8,6 @@ import java.util.Set;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
@@ -22,9 +21,7 @@ import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.domain.common.dto.CompetitorDTOImpl;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
@@ -109,27 +106,8 @@ public class CompetitorPanel extends SimplePanel {
public void onClick(ClickEvent event) {
Set<CompetitorDTO> competitors = competitorSelectionModel.getSelectedSet();
if (competitors.size() == 0){
Window.alert(stringMessages.selectAtLeastOneCompetitorForInvitation());
} else {
boolean emailProvidedForAll = isEmailProvidedForAll(competitors);
if (emailProvidedForAll) {
openChooseEventDialogAndSendMails(competitors);
} else {
Window.alert(stringMessages.notAllCompetitorsProvideEmail());
}
}
}
private boolean isEmailProvidedForAll(Iterable<CompetitorDTO> allCompetitors) {
for (CompetitorDTO competitor : allCompetitors) {
if (!competitor.hasEmail()) {
return false;
}
}
return true;
CompetitorInvitationHelper helper = new CompetitorInvitationHelper(sailingService, stringMessages, errorReporter);
helper.inviteCompetitors(competitors, leaderboardName);
}
});
buttonPanel.add(inviteCompetitorsButton);
@@ -212,37 +190,6 @@ public class CompetitorPanel extends SimplePanel {
dialog.ensureDebugId("CompetitorEditDialog");
dialog.show();
}
private String getLocaleInfo() {
return LocaleInfo.getCurrentLocale().getLocaleName();
}
private void openChooseEventDialogAndSendMails(final Set<CompetitorDTO> competitors) {
new SelectEventAndHostnameDialog(sailingService, stringMessages, errorReporter, leaderboardName, new DialogCallback<Pair<EventDTO, String>>() {
@Override
public void ok(Pair<EventDTO, String> result) {
sailingService.inviteCompetitorsForTrackingViaEmail(result.getB(), result.getA(), leaderboardName,
competitors, getLocaleInfo(), new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
Window.alert(stringMessages.sendingMailsFailed() + caught.getMessage());
}
@Override
public void onSuccess(Void result) {
Window.alert(stringMessages.sendingMailsSuccessful());
}
});
}
@Override
public void cancel() {
}
}).show();
}
public void refreshCompetitorList() {
competitorTable.refreshCompetitorList(leaderboardName);
@@ -18,8 +18,7 @@ public class RaceLogCompetitorRegistrationDialog extends AbstractCompetitorRegis
public RaceLogCompetitorRegistrationDialog(String boatClass, SailingServiceAsync sailingService, StringMessages stringMessages,
ErrorReporter errorReporter, boolean editable, String leaderboardName, String raceColumnName, String fleetName,
com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback<Set<CompetitorDTO>> callback) {
super(sailingService, stringMessages, errorReporter, editable, callback, boatClass);
this.leaderboardName = leaderboardName;
super(sailingService, stringMessages, errorReporter, editable, callback, leaderboardName, boatClass);
this.raceColumnName = raceColumnName;
this.fleetName = fleetName;
}
@@ -126,6 +126,7 @@ public class RaceLogCourseManagementWidget extends CourseManagementWidget {
@Override
public void onSuccess(RaceCourseDTO result) {
updateWaypointsAndControlPoints(result);
marks.refresh(result.getMarks());
}
@Override
@@ -133,18 +134,5 @@ public class RaceLogCourseManagementWidget extends CourseManagementWidget {
errorReporter.reportError("Could not load course: " + caught.getMessage());
}
});
sailingService.getMarksInRaceLog(leaderboardName, raceColumnName, fleetName,
new AsyncCallback<Iterable<MarkDTO>>() {
@Override
public void onSuccess(Iterable<MarkDTO> result) {
marks.refresh(result);
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not load marks: " + caught.getMessage());
}
});
}
}
@@ -11,13 +11,10 @@ import com.sap.sse.gwt.client.ErrorReporter;
public class RegattaLogCompetitorRegistrationDialog extends AbstractCompetitorRegistrationsDialog {
private String leaderboardName;
public RegattaLogCompetitorRegistrationDialog(String boatClass, SailingServiceAsync sailingService, StringMessages stringMessages,
ErrorReporter errorReporter, boolean editable, String leaderboardName,
com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback<Set<CompetitorDTO>> callback) {
super(sailingService, stringMessages, errorReporter, editable, callback, boatClass);
this.leaderboardName = leaderboardName;
super(sailingService, stringMessages, errorReporter, editable, callback, leaderboardName, boatClass);
}
@Override
@@ -225,7 +225,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
declinationCheckbox.setValue(true);
trackableRacesPanel.add(declinationCheckbox);
final CheckBox simulateWithStartTimeNow = new CheckBox(stringMessages.simulateWithStartTimeNow());
final CheckBox simulateWithStartTimeNow = new CheckBox(stringMessages.simulateAsLiveRace());
simulateWithStartTimeNow.setWordWrap(false);
simulateWithStartTimeNow.setValue(false);
trackableRacesPanel.add(simulateWithStartTimeNow);
@@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.ColumnFormatter;
import com.google.gwt.user.client.ui.HorizontalPanel;
@@ -44,6 +45,7 @@ import com.sap.sailing.gwt.ui.client.shared.controls.SelectionCheckboxColumn;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.TracTracConfigurationDTO;
import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO;
import com.sap.sse.common.Duration;
import com.sap.sse.common.util.NaturalComparator;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
@@ -83,7 +85,8 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
private LabeledAbstractFilterablePanel<TracTracRaceRecordDTO> racesFilterablePanel;
private CellTable<TracTracRaceRecordDTO> racesTable;
private static final String ZERO_AS_STRING = "0";
public TracTracEventManagementPanel(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
RegattaRefresher regattaRefresher, StringMessages stringMessages) {
super(sailingService, regattaRefresher, errorReporter, new RaceSelectionModel(), true, stringMessages);
@@ -229,17 +232,12 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
protected HorizontalPanel createRacesPanel() {
HorizontalPanel racesPanel = new HorizontalPanel();
CaptionPanel trackableRacesPanel = createTrackableRacesPanel();
racesPanel.add(trackableRacesPanel);
racesPanel.setCellWidth(trackableRacesPanel, "50%");
CaptionPanel trackedRacesPanel = createTrackedRacesPanel();
racesPanel.add(trackedRacesPanel);
racesPanel.setCellWidth(trackedRacesPanel, "50%");
return racesPanel;
}
@@ -276,10 +274,32 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
correctWindCheckBox.setWordWrap(false);
correctWindCheckBox.setValue(Boolean.TRUE);
final CheckBox simulateWithStartTimeNowCheckBox = new CheckBox(stringMessages.simulateWithStartTimeNow());
final TextBox offsetToStartTimeOfSimulatedRaceTextBox = new TextBox();
offsetToStartTimeOfSimulatedRaceTextBox.setWidth("40px");
offsetToStartTimeOfSimulatedRaceTextBox.setEnabled(false);
offsetToStartTimeOfSimulatedRaceTextBox.setValue(ZERO_AS_STRING);
final CheckBox simulateWithStartTimeNowCheckBox = new CheckBox(stringMessages.simulateAsLiveRace());
simulateWithStartTimeNowCheckBox.ensureDebugId("SimulateWithStartTimeNowCheckBox");
simulateWithStartTimeNowCheckBox.setWordWrap(false);
simulateWithStartTimeNowCheckBox.setValue(Boolean.FALSE);
simulateWithStartTimeNowCheckBox.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
offsetToStartTimeOfSimulatedRaceTextBox.setEnabled(simulateWithStartTimeNowCheckBox.getValue());
offsetToStartTimeOfSimulatedRaceTextBox.setFocus(simulateWithStartTimeNowCheckBox.getValue());
}
});
final FlowPanel simulateAsLiveRacePanel = new FlowPanel();
simulateAsLiveRacePanel.add(simulateWithStartTimeNowCheckBox);
final Label offsetToStartLabel = new Label(stringMessages.simulateWithOffset());
final HorizontalPanel simulateWithOffsetPanel = new HorizontalPanel();
simulateWithOffsetPanel.add(offsetToStartLabel);
simulateWithOffsetPanel.add(offsetToStartTimeOfSimulatedRaceTextBox);
final CheckBox ignoreTracTracMarkPassingsCheckbox = new CheckBox(stringMessages.useInternalAlgorithm());
ignoreTracTracMarkPassingsCheckbox.setWordWrap(false);
ignoreTracTracMarkPassingsCheckbox.setValue(Boolean.FALSE);
@@ -287,8 +307,9 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
layoutTable.setWidget(1, 0, trackSettingsLabel);
layoutTable.setWidget(1, 1, trackWindCheckBox);
layoutTable.setWidget(2, 1, correctWindCheckBox);
layoutTable.setWidget(3, 1, simulateWithStartTimeNowCheckBox);
layoutTable.setWidget(4, 1, ignoreTracTracMarkPassingsCheckbox);
layoutTable.setWidget(3, 1, simulateAsLiveRacePanel);
layoutTable.setWidget(4, 1, simulateWithOffsetPanel);
layoutTable.setWidget(5, 1, ignoreTracTracMarkPassingsCheckbox);
// Filter
Label racesFilterLabel = new Label(stringMessages.filterRacesByName() + ":");
@@ -310,8 +331,8 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
};
racesFilterablePanel.getTextBox().ensureDebugId("TrackableRacesFilterTextBox");
layoutTable.setWidget(5, 0, racesFilterLabel);
layoutTable.setWidget(5, 1, racesFilterablePanel);
layoutTable.setWidget(6, 0, racesFilterLabel);
layoutTable.setWidget(6, 1, racesFilterablePanel);
// Races
TextColumn<TracTracRaceRecordDTO> regattaNameColumn = new TextColumn<TracTracRaceRecordDTO>() {
@@ -357,7 +378,6 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
};
raceVisibilityColumn.setSortable(true);
SelectionCheckboxColumn<TracTracRaceRecordDTO> selectionCheckboxColumn = new SelectionCheckboxColumn<TracTracRaceRecordDTO>(tableResources.cellTableStyle().cellTableCheckboxSelected(),
tableResources.cellTableStyle().cellTableCheckboxDeselected(), tableResources.cellTableStyle().cellTableCheckboxColumnCell()) {
@Override
@@ -381,26 +401,24 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
raceNameColumn, boatClassColumn, raceStartTrackingColumn, raceStatusColumn));
racesTable.setSelectionModel(selectionCheckboxColumn.getSelectionModel(), selectionCheckboxColumn.getSelectionManager());
racesTable.setWidth("100%");
raceList.addDataDisplay(racesTable);
layoutTable.setWidget(6, 0, racesTable);
cellFormatter.setColSpan(6, 0, 2);
Button startTrackingButton = new Button(stringMessages.startTracking());
startTrackingButton.ensureDebugId("StartTrackingButton");
startTrackingButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
Duration offsetToStartTimeOfSimulatedRace = null;
if(simulateWithStartTimeNowCheckBox.getValue().booleanValue()) {
offsetToStartTimeOfSimulatedRace = getMillisecondsDurationFromMinutesAsString(offsetToStartTimeOfSimulatedRaceTextBox.getValue());
}
trackSelectedRaces(trackWindCheckBox.getValue(), correctWindCheckBox.getValue(),
simulateWithStartTimeNowCheckBox.getValue(), ignoreTracTracMarkPassingsCheckbox.getValue());
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassingsCheckbox.getValue());
}
});
layoutTable.setWidget(7, 1, startTrackingButton);
trackableRacesPanel.setContentWidget(layoutTable);
return trackableRacesPanel;
}
@@ -462,6 +480,17 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
return boatClassNames.substring(0, boatClassNames.length() - 2);
}
private Duration getMillisecondsDurationFromMinutesAsString(String minutesAsString) {
Duration result = null;
if (minutesAsString != null) {
Double minutesAsDouble = Double.parseDouble(minutesAsString);
if (minutesAsDouble != null) {
result = Duration.ONE_MINUTE.times(minutesAsDouble.longValue());
}
}
return result;
}
private void fillConfigurations() {
this.sailingService.getPreviousTracTracConfigurations(new MarkedAsyncCallback<List<TracTracConfigurationDTO>>(
@@ -551,7 +580,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}));
}
private void trackSelectedRaces(boolean trackWind, boolean correctWind, final boolean simulateWithStartTimeNow, boolean ignoreTracTracMarkPassings) {
private void trackSelectedRaces(boolean trackWind, boolean correctWind, final Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings) {
String liveURI = liveURITextBox.getValue();
String storedURI = storedURITextBox.getValue();
String courseDesignUpdateURI = tracTracUpdateURITextBox.getValue();
@@ -577,7 +606,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
if (checkBoatClassOK(selectedRegatta, selectedRaces)) {
sailingService.trackWithTracTrac(regattaIdentifier, selectedRaces, liveURI, storedURI,
courseDesignUpdateURI, trackWind, correctWind, simulateWithStartTimeNow, ignoreTracTracMarkPassings, tractracUsername,
courseDesignUpdateURI, trackWind, correctWind, offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, tractracUsername,
tractracPassword, new MarkedAsyncCallback<Void>(new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
@@ -86,6 +86,7 @@ import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO;
import com.sap.sailing.gwt.ui.shared.VenueDTO;
import com.sap.sailing.gwt.ui.shared.WindDTO;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
import com.sap.sse.common.Duration;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -116,7 +117,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
void trackWithTracTrac(RegattaIdentifier regattaToAddTo, Iterable<TracTracRaceRecordDTO> rrs, String liveURI,
String storedURI, String courseDesignUpdateURI, boolean trackWind, boolean correctWindByDeclination,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword) throws Exception;
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword) throws Exception;
void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable<SwissTimingRaceRecordDTO> rrs, String hostname, int port,
boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm) throws Exception;
@@ -78,6 +78,7 @@ import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO;
import com.sap.sailing.gwt.ui.shared.VenueDTO;
import com.sap.sailing.gwt.ui.shared.WindDTO;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
@@ -114,10 +115,10 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
* @param liveURI
* may be <code>null</code> or the empty string in which case the server will use the
* {@link TracTracRaceRecordDTO#liveURI} from the <code>rr</code> race record.
* @param simulateWithStartTimeNow
* if <code>true</code>, the connector will adjust the time stamps of all events received such that the
* @param offsetToStartTimeOfSimulatedRace
* if not <code>null</code>, the connector will adjust the time stamps of all events received such that the
* first mark passing for the first waypoint will be set to "now." It will delay the forwarding of all
* events received such that they seem to be sent in "real-time." So, more or less the time points
* events received such that they seem to be sent in "real-time" plus the <code>offsetToStartTimeOfSimulatedRace</code>. So, more or less the time points
* attached to the events sent to the receivers will again approximate the wall time.
* @param useInternalMarkPassingAlgorithm
* whether or not to ignore the TracTrac-provided mark passings; if <code>true</code>, a separate mark
@@ -128,7 +129,7 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
*/
void trackWithTracTrac(RegattaIdentifier regattaToAddTo, Iterable<TracTracRaceRecordDTO> rrs, String liveURI,
String storedURI, String courseDesignUpdateURI, boolean trackWind, boolean correctWindByDeclination,
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, String tracTracUsername,
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername,
String tracTracPassword, AsyncCallback<Void> callback);
void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable<SwissTimingRaceRecordDTO> rrs,
@@ -361,7 +361,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String successfullyUpdatedScores();
String errorUpdatingScoresForLeaderboard(String leaderboardName, String message);
String maneuverTypesToShowWhenCompetitorIsClicked();
String simulateWithStartTimeNow();
String simulateAsLiveRace();
String simulateWithOffset();
String boatClassDoesNotMatchSelectedRegatta(String boatClass);
String regattaExistForSelectedBoatClass();
String reload();
@@ -436,7 +437,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String overallDetailsToShow();
String hhmmssUnit();
String actionAddWindData();
String valueMustBeBetweenMinMax(String name, String minValue, String maxValue);
String valueMustBeBetweenMinMax(String name, int minValue, int maxValue);
String valueMustBeGreaterThan(String name, String minValue);
String optional();
String pleaseEnterAValue();
String latitude();
@@ -1444,4 +1446,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String requiresValidRegatta();
String couldNotObtainRace(String regattaLikeName, String raceColumnName, String fleetName, String technicalErrorMessage);
String errorTryingToCreateEmbeddedMap(String message);
String transparentBufferLineOnHover();
String bufferLineStrokeWeight();
}
@@ -371,7 +371,8 @@ apply=Apply
successfullyUpdatedScores=Successfully updated scores
errorUpdatingScoresForLeaderboard=Error updating scores for leaderboard {0}: {1}
maneuverTypesToShowWhenCompetitorIsClicked=Maneuver types to show when competitor is clicked
simulateWithStartTimeNow=Simulate with "now" as start time
simulateAsLiveRace=Simulate as live race
simulateWithOffset=Offset before start in minutes:
boatClassDoesNotMatchSelectedRegatta=The selected races contain boat classes which are not the same as the boat class ''{0}'' of the selected regatta. No races will be loaded.
regattaExistForSelectedBoatClass=There is at least one regatta for the selected boat classes. Really create default regatta(s) for those race(s)?
reload=Reload
@@ -456,6 +457,7 @@ totalAverageSpeedOverGroundTooltip=Average speed over ground across the regatta.
hhmmssUnit=hh:mm:ss
actionAddWindData=Add wind data
valueMustBeBetweenMinMax=The value of ''{0}'' must be between {1} and {2}.
valueMustBeGreaterThan=The value of ''{0}'' must be greater than {1}.
optional=optional
pleaseEnterAValue=Please enter a value.
latitude=Latitude
@@ -1410,4 +1412,6 @@ selectALeaderboardGroup=Select a leaderboard group...
pleaseSelect=Please select
requiresValidRegatta=This page requires a valid regatta, race column and fleet name to identify the race to show.
couldNotObtainRace=Could not obtain a race with name {1} for fleet {2} for a regatta with name {0}: {3}
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
transparentBufferLineOnHover=Transparent buffer lines on hover of helplines
bufferLineStrokeWeight=Buffer line stroke weight
@@ -372,7 +372,8 @@ apply=Übernehmen
successfullyUpdatedScores=Ergebnisse erfolgreich aktualisiert
errorUpdatingScoresForLeaderboard=Fehler beim Aktualisieren der Ergebnisse für {0}: {1}
maneuverTypesToShowWhenCompetitorIsClicked=Anzuzeigende Manövertypen für angeklickte Teilnehmer
simulateWithStartTimeNow=Simulieren mit "jetzt" als Startzeit
simulateAsLiveRace=Simuliere als Live Rennen
simulateWithOffset=Zeit bis zum Start in Minuten:
boatClassDoesNotMatchSelectedRegatta=Die ausgewählten Rennen enthalten eine Bootsklasse, die nicht der Bootsklasse der ausgewählten Regatta ''{0}'' entspricht. Es werden keine Rennen geladen.
regattaExistForSelectedBoatClass=Es gibt mindestens eine Regatta zu den ausgewählten Bootsklassen. Dennoch Default-Regatta für diese(s) Rennen anlegen?
reload=Neu laden
@@ -456,7 +457,8 @@ totalAverageSpeedOverGround=\u2205 FüG
totalAverageSpeedOverGroundTooltip=Durchschnittliche Fahrt über Grund über die gesamte Regatta.
hhmmssUnit=hh:mm:ss
actionAddWindData=Winddaten hinzufügen
valueMustBeBetweenMinMax=Der Wert von ''{0}'' muß zwischen {1} und {2} sein.
valueMustBeBetweenMinMax=Der Wert von ''{0}'' muss zwischen {1} und {2} sein.
valueMustBeGreaterThan=Der Wert von ''{0}'' muss größer als {1} sein.
optional=optional
pleaseEnterAValue=Bitte geben Sie einen Wert ein.
latitude=Breite
@@ -1401,4 +1403,6 @@ selectALeaderboardGroup=Bitte eine Ranglisten-Gruppe auswählen...
pleaseSelect=Bitte auswählen
requiresValidRegatta=Diese Seite benötigt eine gültige Regatta, Rennspalte und einen gültigen Gruppennamen um die anzuzeigende Wettfahrt zu identifizieren.
couldNotObtainRace=Wettfahrt namens {1} für Gruppe {2} in einer Regatta names {0} konnte nicht gefunden werden: {3}
errorTryingToCreateEmbeddedMap=Fehler beim Erstellen der eingebetteten Karte: {0}
errorTryingToCreateEmbeddedMap=Fehler beim Erstellen der eingebetteten Karte: {0}
transparentBufferLineOnHover=Transparente Pufferlinien bei Maus über Hilfslinien
bufferLineStrokeWeight=Linienbreite der Pufferlinien
@@ -364,7 +364,8 @@ apply=Применить
successfullyUpdatedScores=Очки обновлены успешно
errorUpdatingScoresForLeaderboard=Ошибка обновления очков для таблицы лидеров {0}: {1}
maneuverTypesToShowWhenCompetitorIsClicked=Типы маневров для отображения при нажатии на участника
simulateWithStartTimeNow=Моделирования с "сейчас" в качестве времени начала
simulateAsLiveRace=Simulate as live race
simulateWithOffset=Offset before start in minutes:
boatClassDoesNotMatchSelectedRegatta=Выбранные гонки содержат классы судов не соответствующие классу судов ''{0}'' выбранной регаты.
regattaExistForSelectedBoatClass=Есть только одна регата для выбранных классов судов.
reload=Перезагрузить
@@ -440,6 +441,7 @@ totalAverageSpeedOverGroundTooltip=Средняя скорость относи
hhmmssUnit=чч:мм:сс
actionAddWindData=Добавить данные о ветре
valueMustBeBetweenMinMax=Значение ''{0}''должно быть в пределах от {1} до {2}.
valueMustBeGreaterThan=The value of ''{0}'' must be greater than {1}.
optional=Дополнительно
pleaseEnterAValue=Введите, пожалуйста, значение.
latitude=Широта
@@ -1340,4 +1342,6 @@ selectALeaderboardGroup=Select a leaderboard group...
pleaseSelect=Please select
requiresValidRegatta=This page requires a valid regatta, race column and fleet name to identify the race to show.
couldNotObtainRace=Could not obtain a race with name {1} for fleet {2} for a regatta with name {0}: {3}
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
transparentBufferLineOnHover=Transparent buffer lines on hover of helplines
bufferLineStrokeWeight=Buffer line stroke weight
@@ -538,6 +538,7 @@ connectors=Connectors
dampeningInterval=Dampening Interval
trackBasedEstimationWindSourceTypeTooltip=Calculated data from the competitor tracks
valueMustBeBetweenMinMax=The value of ''{0}'' must be between {1} and {2}.
valueMustBeGreaterThan=The value of ''{0}'' must be greater than {1}.
orMultipleEmails=or multiple E-Mails separated by comma
searchEvents=Search for events
explainNoConnectionsFromReplicas=No connections from a replica found. You can connect replicas by using their AdminConsole.
@@ -1072,7 +1073,8 @@ trackWind=Track Wind
rawFixes=All fixes (including outliers)
showCompetitorFullNameColumn=Show Competitor Full Name
disableRaceFilter=Disable filter
simulateWithStartTimeNow=Simulate with "now" as start time
simulateAsLiveRace=Simulate as live race
simulateWithOffset=Offset before start in minutes:
polarSheetOutlierDetectionRadiusTooltip=The radius used in the distance based outlierndetection algorithm.
noWindFixesAvailable=No Wind-Fixes available.
correctScoreFor=Correct score for competitor {0} in race {1}
@@ -1355,4 +1357,6 @@ selectALeaderboardGroup=Select a leaderboard group...
pleaseSelect=Please select
requiresValidRegatta=This page requires a valid regatta, race column and fleet name to identify the race to show.
couldNotObtainRace=Could not obtain a race with name {1} for fleet {2} for a regatta with name {0}: {3}
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
transparentBufferLineOnHover=Transparent buffer lines on hover of helplines
bufferLineStrokeWeight=Buffer line stroke weight
@@ -10,7 +10,7 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.communication.media.SailingImageDTO;
import com.sap.sse.gwt.client.media.ImageDTO;
public class GalleryImageHolder extends Widget implements HasClickHandlers {
@@ -22,7 +22,7 @@ public class GalleryImageHolder extends Widget implements HasClickHandlers {
@UiField
DivElement imageHolderUi;
public GalleryImageHolder(SailingImageDTO video) {
public GalleryImageHolder(ImageDTO video) {
setElement(uiBinder.createAndBindUi(this));
imageHolderUi.getStyle().setBackgroundImage("url(\"" + video.getSourceRef() + "\")");
@@ -11,9 +11,9 @@ import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.home.communication.media.SailingVideoDTO;
import com.sap.sailing.gwt.ui.common.client.YoutubeApi;
import com.sap.sse.common.media.MediaSubType;
import com.sap.sse.gwt.client.media.VideoDTO;
public class VideoThumbnail extends Widget implements HasClickHandlers {
@@ -28,7 +28,7 @@ public class VideoThumbnail extends Widget implements HasClickHandlers {
@UiField
ImageElement thumbnailUi;
public VideoThumbnail(SailingVideoDTO video) {
public VideoThumbnail(VideoDTO video) {
setElement(uiBinder.createAndBindUi(this));
getElement().addClassName("videoThumbnail");
captionUi.setInnerText(video.getTitle());
@@ -0,0 +1,57 @@
package com.sap.sailing.gwt.ui.client.shared.racemap;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.maps.client.events.click.ClickMapHandler;
import com.google.gwt.maps.client.events.mouseout.MouseOutMapEvent;
import com.google.gwt.maps.client.events.mouseout.MouseOutMapHandler;
import com.google.gwt.maps.client.events.mouseover.MouseOverMapEvent;
import com.google.gwt.maps.client.events.mouseover.MouseOverMapHandler;
import com.google.gwt.maps.client.overlays.Polyline;
import com.google.gwt.maps.client.overlays.PolylineOptions;
public class Hoverline {
private static final double TRANSPARENT = 0;
private static final double VISIBLE = 0.2d;
private final Polyline hoverline;
private final PolylineOptions options;
public Hoverline(final Polyline polyline, PolylineOptions polylineOptions, final RaceMap map) {
this.options = PolylineOptions.newInstance();
this.options.setClickable(polylineOptions.getClickable());
this.options.setGeodesic(polylineOptions.getGeodesic());
this.options.setMap(polyline.getMap());
this.options.setPath(polyline.getPath());
this.options.setStrokeColor(polylineOptions.getStrokeColor());
this.options.setZindex(polylineOptions.getZindex());
this.hoverline = Polyline.newInstance(this.options);
this.hoverline.setVisible(false);
polyline.addMouseOverHandler(new MouseOverMapHandler() {
@Override
public void onEvent(MouseOverMapEvent event) {
options.setStrokeOpacity(map.getSettings().getTransparentHoverlines() ? TRANSPARENT : VISIBLE);
options.setStrokeWeight(map.getSettings().getHoverlineStrokeWeight());
options.setVisible(true);
hoverline.setOptions(options);
}
});
hoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
@Override
public void onEvent(MouseOutMapEvent event) {
hoverline.setVisible(false);
}
});
}
public HandlerRegistration addClickHandler(ClickMapHandler handler) {
return this.hoverline.addClickHandler(handler);
}
public HandlerRegistration addMouseOutMoveHandler(MouseOutMapHandler handler) {
return this.hoverline.addMouseOutMoveHandler(handler);
}
public HandlerRegistration addMouseOverHandler(MouseOverMapHandler handler) {
return this.hoverline.addMouseOverHandler(handler);
}
}
@@ -1159,7 +1159,6 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
Polyline tail = fixesAndTails.getTail(competitorDTO);
if (tail == null) {
tail = fixesAndTails.createTailAndUpdateIndices(competitorDTO, tailsFromTime, tailsToTime, this);
tail.setMap(map);
} else {
fixesAndTails.updateTail(tail, competitorDTO, tailsFromTime, tailsToTime,
(int) (timeForPositionTransitionMillis==-1?-1:timeForPositionTransitionMillis/2));
@@ -1306,17 +1305,18 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
pointsAsArray.insertAt(0, advantageLinePos1);
pointsAsArray.insertAt(1, advantageLinePos2);
advantageLine.setPath(pointsAsArray);
advantageLine.setMap(map);
Hoverline advantageHoverline = new Hoverline(advantageLine, options, this);
advantageLineMouseOverHandler = new AdvantageLineMouseOverMapHandler(
bearingOfCombinedWindInDeg, new Date(windFix.measureTimepoint));
advantageLine.addMouseOverHandler(advantageLineMouseOverHandler);
advantageLine.addMouseOutMoveHandler(new MouseOutMapHandler() {
advantageHoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
@Override
public void onEvent(MouseOutMapEvent event) {
map.setTitle("");
}
});
advantageLine.setMap(map);
} else {
advantageLine.getPath().removeAt(1);
advantageLine.getPath().removeAt(0);
@@ -1562,20 +1562,20 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
pointsAsArray = MVCArray.newInstance();
lineToShowOrRemoveOrUpdate = Polyline.newInstance(options);
lineToShowOrRemoveOrUpdate.setPath(pointsAsArray);
lineToShowOrRemoveOrUpdate.setMap(map);
Hoverline lineToShowOrRemoveOrUpdateHoverline = new Hoverline(lineToShowOrRemoveOrUpdate, options, this);
lineToShowOrRemoveOrUpdate.addMouseOverHandler(new MouseOverMapHandler() {
@Override
public void onEvent(MouseOverMapEvent event) {
map.setTitle(lineInfoProvider.getLineInfo());
}
});
lineToShowOrRemoveOrUpdate.addMouseOutMoveHandler(new MouseOutMapHandler() {
lineToShowOrRemoveOrUpdateHoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
@Override
public void onEvent(MouseOutMapEvent event) {
map.setTitle("");
}
});
lineToShowOrRemoveOrUpdate.setMap(map);
} else {
pointsAsArray = lineToShowOrRemoveOrUpdate.getPath();
pointsAsArray.removeAt(1);
@@ -2329,6 +2329,12 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
updateCoordinateSystemFromSettings();
requiredRedraw = true;
}
if (newSettings.getTransparentHoverlines() != settings.getTransparentHoverlines()) {
settings.setTransparentHoverlines(newSettings.getTransparentHoverlines());
}
if (newSettings.getHoverlineStrokeWeight() != settings.getHoverlineStrokeWeight()) {
settings.setHoverlineStrokeWeight(newSettings.getHoverlineStrokeWeight());
}
if (requiredRedraw) {
redraw();
}
@@ -2513,23 +2519,25 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
public Polyline createTail(final CompetitorDTO competitor, List<LatLng> points) {
PolylineOptions options = createTailStyle(competitor, displayHighlighted(competitor));
Polyline result = Polyline.newInstance(options);
MVCArray<LatLng> pointsAsArray = MVCArray.newInstance(points.toArray(new LatLng[0]));
result.setPath(pointsAsArray);
result.addClickHandler(new ClickMapHandler() {
result.setMap(map);
Hoverline resultHoverline = new Hoverline(result, options, this);
final ClickMapHandler clickHandler = new ClickMapHandler() {
@Override
public void onEvent(ClickMapEvent event) {
showCompetitorInfoWindow(competitor, event.getMouseEvent().getLatLng());
}
});
};
result.addClickHandler(clickHandler);
resultHoverline.addClickHandler(clickHandler);
result.addMouseOverHandler(new MouseOverMapHandler() {
@Override
public void onEvent(MouseOverMapEvent event) {
map.setTitle(competitor.getSailID() + ", " + competitor.getName());
}
});
result.addMouseOutMoveHandler(new MouseOutMapHandler() {
resultHoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
@Override
public void onEvent(MouseOutMapEvent event) {
map.setTitle("");
@@ -19,6 +19,10 @@ public class RaceMapSettings extends AbstractSettings {
private RaceMapZoomSettings zoomSettings;
private RaceMapHelpLinesSettings helpLinesSettings;
private boolean transparentHoverlines = true;
private int hoverlineStrokeWeight = 10;
private long tailLengthInMilliseconds = 100000l;
@@ -55,6 +59,8 @@ public class RaceMapSettings extends AbstractSettings {
public RaceMapSettings(RaceMapSettings settings) {
this.buoyZoneRadiusInMeters = settings.buoyZoneRadiusInMeters;
this.helpLinesSettings = new RaceMapHelpLinesSettings(settings.getHelpLinesSettings().getVisibleHelpLineTypes());
this.transparentHoverlines = settings.transparentHoverlines;
this.hoverlineStrokeWeight = settings.hoverlineStrokeWeight;
this.maneuverTypesToShow = settings.maneuverTypesToShow;
this.showDouglasPeuckerPoints = settings.showDouglasPeuckerPoints;
this.showOnlySelectedCompetitors = settings.showOnlySelectedCompetitors;
@@ -153,6 +159,22 @@ public class RaceMapSettings extends AbstractSettings {
public void setHelpLinesSettings(RaceMapHelpLinesSettings helpLinesSettings) {
this.helpLinesSettings = helpLinesSettings;
}
public boolean getTransparentHoverlines() {
return this.transparentHoverlines;
}
public void setTransparentHoverlines(boolean transparentHoverlines) {
this.transparentHoverlines = transparentHoverlines;
}
public int getHoverlineStrokeWeight() {
return this.hoverlineStrokeWeight;
}
public void setHoverlineStrokeWeight(int hoverlineStrokeWeight) {
this.hoverlineStrokeWeight = hoverlineStrokeWeight;
}
public boolean isShowSelectedCompetitorsInfo() {
return showSelectedCompetitorsInfo;
@@ -24,11 +24,14 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes;
import com.sap.sse.common.Util;
import com.sap.sse.gwt.client.controls.IntegerBox;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.Validator;
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<RaceMapSettings> {
private static final int MAX_BUOY_ZONE_RADIUS_IN_METERS = 100;
private static final int MAX_STROKE_WEIGHT = 33;
//Initializing the lists to prevent a null pointer exception in the first validation call
private List<Util.Pair<CheckBox, ManeuverType>> checkboxAndManeuverType = new ArrayList<Util.Pair<CheckBox, ManeuverType>>();
private List<Util.Pair<CheckBox, ZoomTypes>> checkboxAndZoomType = new ArrayList<Util.Pair<CheckBox,ZoomTypes>>();
@@ -43,6 +46,8 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
private CheckBox showSelectedCompetitorsInfoCheckBox;
private LongBox tailLengthBox;
private DoubleBox buoyZoneRadiusBox;
private CheckBox transparentHoverlines;
private IntegerBox hoverlineStrokeWeight;
private boolean showViewSimulation;
private final StringMessages stringMessages;
@@ -211,6 +216,17 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
vp.add(createHelpLineCheckBox(dialog, HelpLineTypes.STARTLINETOFIRSTMARKTRIANGLE));
vp.add(createHelpLineCheckBox(dialog, HelpLineTypes.COURSEGEOMETRY));
transparentHoverlines = dialog.createCheckbox(stringMessages.transparentBufferLineOnHover());
transparentHoverlines.setValue(initialSettings.getTransparentHoverlines());
vp.add(transparentHoverlines);
HorizontalPanel hoverlineStrokeWeightPanel = new HorizontalPanel();
Label hoverlineStrokeWeightLabel = new Label(stringMessages.bufferLineStrokeWeight() + ":");
hoverlineStrokeWeightPanel.add(hoverlineStrokeWeightLabel);
hoverlineStrokeWeight = dialog.createIntegerBox(initialSettings.getHoverlineStrokeWeight(), 3);
hoverlineStrokeWeightPanel.add(hoverlineStrokeWeight);
vp.add(hoverlineStrokeWeightPanel);
return vp;
}
@@ -267,6 +283,8 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
result.setBuoyZoneRadiusInMeters(value);
}
}
result.setTransparentHoverlines(transparentHoverlines.getValue());
result.setHoverlineStrokeWeight(hoverlineStrokeWeight.getValue());
return result;
}
@@ -304,8 +322,10 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
if (valueToValidate.getHelpLinesSettings().isVisible(HelpLineTypes.BOATTAILS) && valueToValidate.getTailLengthInMilliseconds() <= 0) {
errorMessage = stringMessages.tailLengthMustBePositive();
} else if (valueToValidate.getHelpLinesSettings().isVisible(HelpLineTypes.BUOYZONE)
&& (valueToValidate.getBuoyZoneRadiusInMeters() < 0.0 || valueToValidate.getBuoyZoneRadiusInMeters() > 100.0)) {
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.buoyZone(), "0", "100");
&& (valueToValidate.getBuoyZoneRadiusInMeters() < 0 || valueToValidate.getBuoyZoneRadiusInMeters() > MAX_BUOY_ZONE_RADIUS_IN_METERS)) {
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.buoyZone(), 0, 100);
} else if (valueToValidate.getHoverlineStrokeWeight() < 0 || valueToValidate.getHoverlineStrokeWeight() > MAX_STROKE_WEIGHT) {
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.bufferLineStrokeWeight(), 0, MAX_STROKE_WEIGHT);
}
return errorMessage;
}
@@ -444,12 +444,7 @@ import com.sap.sse.common.Util.Triple;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.impl.TimeRangeImpl;
import com.sap.sse.common.mail.MailException;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.MediaUtils;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.filestorage.FileStorageService;
import com.sap.sse.filestorage.InvalidPropertiesException;
import com.sap.sse.gwt.client.ServerInfoDTO;
@@ -465,6 +460,11 @@ import com.sap.sse.replication.ReplicationMasterDescriptor;
import com.sap.sse.replication.ReplicationService;
import com.sap.sse.replication.impl.ReplicaDescriptor;
import com.sap.sse.security.SessionUtils;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.MediaUtils;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
import com.sap.sse.util.ServiceTrackerFactory;
import com.sapsailing.xrr.structureimport.eventimport.RegattaJSON;
@@ -1023,7 +1023,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public void trackWithTracTrac(RegattaIdentifier regattaToAddTo, Iterable<TracTracRaceRecordDTO> rrs, String liveURI, String storedURI,
String courseDesignUpdateURI, boolean trackWind, final boolean correctWindByDeclination,
final boolean simulateWithStartTimeNow, final boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword)
final Duration offsetToStartTimeOfSimulatedRace, final boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword)
throws Exception {
logger.info("tracWithTracTrac for regatta " + regattaToAddTo + " for race records " + rrs + " with liveURI " + liveURI
+ " and storedURI " + storedURI);
@@ -1054,7 +1054,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
new URI(courseDesignUpdateURI), new MillisecondsTimePoint(record.getTrackingStartTime().asMillis()),
new MillisecondsTimePoint(record.getTrackingEndTime().asMillis()),
getRaceLogStore(), getRegattaLogStore(),
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, simulateWithStartTimeNow,
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, offsetToStartTimeOfSimulatedRace,
useInternalMarkPassingAlgorithm, tracTracUsername, tracTracPassword, record.getRaceStatus(), record.getRaceVisibility());
if (trackWind) {
new Thread("Wind tracking starter for race " + record.getEventName() + "/" + record.getName()) {
@@ -1946,7 +1946,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
result.totalLegsCount = trackedRace.getRace().getCourse().getLegs().size();
result.currentLegNumber = trackedRace.getLastLegStarted(dateAsTimePoint);
result.marks = new HashSet<MarkDTO>();
result.course = convertToRaceCourseDTO(trackedRace.getRace().getCourse(), trackedRace, dateAsTimePoint);
result.course = convertToRaceCourseDTO(trackedRace.getRace().getCourse(), new TrackedRaceMarkPositionFinder(trackedRace), dateAsTimePoint);
// now make sure we don't duplicate the MarkDTO objects but instead use the ones from the RaceCourseDTO
// object and amend them with the Position
result.waypointPositions = new ArrayList<>();
@@ -2020,7 +2020,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
for (Waypoint waypoint : course.getWaypoints()) {
ControlPointDTO controlPointDTO = controlPointCache.get(waypoint.getControlPoint().getId());
if (controlPointDTO == null) {
controlPointDTO = convertToControlPointDTO(waypoint.getControlPoint(), trackedRace, dateAsTimePoint);
controlPointDTO = convertToControlPointDTO(waypoint.getControlPoint(), new TrackedRaceMarkPositionFinder(trackedRace), dateAsTimePoint);
controlPointCache.put(waypoint.getControlPoint().getId(), controlPointDTO);
}
WaypointDTO waypointDTO = new WaypointDTO(waypoint.getName(), controlPointDTO,
@@ -2031,20 +2031,44 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return new RaceCourseDTO(waypointDTOs, allMarks);
}
private ControlPointDTO convertToControlPointDTO(ControlPoint controlPoint, TrackedRace trackedRace, TimePoint timePoint) {
class TrackedRaceMarkPositionFinder implements MarkPositionFinder{
private TrackedRace trackedRace;
public TrackedRaceMarkPositionFinder(TrackedRace trackedRace) {
this.trackedRace = trackedRace;
}
@Override
public Position find(Mark mark, TimePoint at) {
final TimePoint timePointToUse = trackedRace == null ? null :
at == null ? MillisecondsTimePoint.now().minus(trackedRace.getDelayToLiveInMillis()) : at;
final Position result;
if (timePointToUse == null) {
result = null;
} else {
result = trackedRace.getOrCreateTrack(mark).getEstimatedPosition(timePointToUse, /* extrapolate */ false);
}
return result;
}
}
private interface MarkPositionFinder {
Position find(Mark mark, TimePoint at);
}
private ControlPointDTO convertToControlPointDTO(ControlPoint controlPoint, MarkPositionFinder positionFinder, TimePoint timePoint) {
ControlPointDTO result;
final TimePoint timePointToUse = trackedRace == null ? null :
timePoint == null ? MillisecondsTimePoint.now().minus(trackedRace.getDelayToLiveInMillis()) : timePoint;
if (controlPoint instanceof ControlPointWithTwoMarks) {
final Mark left = ((ControlPointWithTwoMarks) controlPoint).getLeft();
final Position leftPos = timePointToUse == null ? null : trackedRace.getOrCreateTrack(left).getEstimatedPosition(timePointToUse, /* extrapolate */ false);
final Position leftPos = positionFinder.find(left, timePoint);
final Mark right = ((ControlPointWithTwoMarks) controlPoint).getRight();
final Position rightPos = timePointToUse == null ? null : trackedRace.getOrCreateTrack(right).getEstimatedPosition(timePointToUse, /* extrapolate */ false);
final Position rightPos = positionFinder.find(right, timePoint);
result = new GateDTO(controlPoint.getId().toString(), controlPoint.getName(), convertToMarkDTO(left, leftPos), convertToMarkDTO(right, rightPos));
} else {
final Position posOfFirst = timePointToUse == null ? null : trackedRace.getOrCreateTrack(controlPoint.getMarks().iterator().next()).
getEstimatedPosition(timePointToUse, /* extrapolate */ false);
result = new MarkDTO(controlPoint.getId().toString(), controlPoint.getName(), posOfFirst == null ? -1 : posOfFirst.getLatDeg(), posOfFirst == null ? -1 : posOfFirst.getLngDeg());
Mark mark = controlPoint.getMarks().iterator().next();
final Position position = positionFinder.find(mark, timePoint);
result = convertToMarkDTO(mark, position);
}
return result;
}
@@ -5156,10 +5180,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
* the mark positions and attach to the {@link MarkDTO}s. If <code>null<c/code>, the current time point
* will be used as default.
*/
private WaypointDTO convertToWaypointDTO(Waypoint waypoint, Map<Serializable, ControlPointDTO> controlPointCache, TrackedRace trackedRace, TimePoint timePoint) {
private WaypointDTO convertToWaypointDTO(Waypoint waypoint, Map<Serializable, ControlPointDTO> controlPointCache, MarkPositionFinder positionFinder, TimePoint timePoint) {
ControlPointDTO cp = controlPointCache.get(waypoint.getControlPoint().getId());
if (cp == null) {
cp = convertToControlPointDTO(waypoint.getControlPoint(), trackedRace, timePoint);
cp = convertToControlPointDTO(waypoint.getControlPoint(), positionFinder, timePoint);
controlPointCache.put(waypoint.getControlPoint().getId(), cp);
}
return new WaypointDTO(waypoint.getName(), cp, waypoint.getPassingInstructions());
@@ -5175,13 +5199,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
* the mark positions and attach to the {@link MarkDTO}s. If <code>null<c/code>, the current time point
* will be used as default.
*/
private RaceCourseDTO convertToRaceCourseDTO(CourseBase course, TrackedRace trackedRace, TimePoint timePoint) {
private RaceCourseDTO convertToRaceCourseDTO(CourseBase course, MarkPositionFinder positionFinder, TimePoint timePoint) {
final RaceCourseDTO result;
if (course != null) {
List<WaypointDTO> waypointDTOs = new ArrayList<WaypointDTO>();
Map<Serializable, ControlPointDTO> controlPointCache = new HashMap<>();
for (Waypoint waypoint : course.getWaypoints()) {
waypointDTOs.add(convertToWaypointDTO(waypoint, controlPointCache, trackedRace, timePoint));
waypointDTOs.add(convertToWaypointDTO(waypoint, controlPointCache, positionFinder, timePoint));
}
result = new RaceCourseDTO(waypointDTOs);
} else {
@@ -5191,13 +5215,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
@Override
public RaceCourseDTO getLastCourseDefinitionInRaceLog(String leaderboardName, String raceColumnName, String fleetName) {
RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
public RaceCourseDTO getLastCourseDefinitionInRaceLog(final String leaderboardName, String raceColumnName, String fleetName) {
final RaceLog raceLog = getRaceLog(leaderboardName, raceColumnName, fleetName);
CourseBase lastPublishedCourse = new LastPublishedCourseDesignFinder(raceLog).analyze();
if (lastPublishedCourse == null) {
lastPublishedCourse = new CourseDataImpl("");
}
return convertToRaceCourseDTO(lastPublishedCourse, /* trackedRace */ null, /* timePoint */ null);
return convertToRaceCourseDTO(lastPublishedCourse, new MarkPositionFinder() {
@Override
public Position find(Mark mark, TimePoint at) {
return getService().getMarkPosition(mark, (LeaderboardThatHasRegattaLike) getService().getLeaderboardByName(leaderboardName), at, raceLog);
}
}, /* timePoint */ MillisecondsTimePoint.now());
}
@Override
@@ -7,6 +7,12 @@
<h5 class="articleSubheadline">December 2015</h5>
<ul class="bulletList">
<li>New line hover behavior in race map. When the mouse is moved onto a line, for example the start line, a transparent,
wider line is activated behind it that acts as a buffer for the thin line, where the text displayed by the hover is still shown.
This makes it easier to hover over the lines. These wider lines can be made semi transparent instead of transparent
by unticking the corresponding checkbox in the settings of the race map. Furthermore the stroke weight of the wider lines can be
configured in the same settings dialog.
</li>
<li>The race viewer (RaceBoard.html) now intelligently chooses a layout that suits the screen size.
When only little horizontal space is available, only the sail number and nationality but not the
competitor's long name is displayed by default. When vertical space is scarce, competitor and wind
@@ -27,7 +27,8 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.operationaltransformation,
com.sap.sse.replication,
com.sap.sse,
com.sap.sse.filestorage
com.sap.sse.filestorage,
com.sap.sse.shared.android
Import-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.common.impl,
com.sap.sailing.domain.common.racelog,
@@ -38,7 +38,7 @@ public class GPSFixWithPolarContext implements HasGPSFixPolarContext {
@Override
public ClusterDTO getWindSpeedRange() {
return new ClusterDTO(windSpeedRangeGroup.getClusterFor(wind.getObject()).toString());
return new ClusterDTO(wind == null || wind.getObject() == null ? "null" : windSpeedRangeGroup.getClusterFor(wind.getObject()).toString());
}
@Override
@@ -8,7 +8,8 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.sap.sailing.domain.common,
com.sap.sailing.domain.shared.android,
org.json.simple;bundle-version="1.1.0",
com.sap.sse.common
com.sap.sse.common,
com.sap.sse.shared.android
Export-Package: com.sap.sailing.server.gateway.deserialization,
com.sap.sailing.server.gateway.deserialization.coursedata.impl,
com.sap.sailing.server.gateway.deserialization.impl,
@@ -1,25 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.server.gateway.serialization.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.server.gateway.serialization.shared.android</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -23,12 +23,12 @@ import com.sap.sailing.server.gateway.serialization.impl.EventBaseJsonSerializer
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.ImageSize;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class EventBaseJsonDeserializer implements JsonDeserializer<EventBase> {
private final JsonDeserializer<Venue> venueDeserializer;
@@ -9,8 +9,8 @@ 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;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventBaseJsonSerializer implements JsonSerializer<EventBase> {
public static final String FIELD_ID = "id";
@@ -14,4 +14,5 @@ Require-Bundle: com.sap.sailing.domain;bundle-version="1.0.0",
org.json.simple,
org.mockito.mockito-core;bundle-version="1.9.5",
org.objenesis;bundle-version="1.3.0",
com.sap.sse.common
com.sap.sse.common,
com.sap.sse.shared.android
@@ -32,8 +32,8 @@ import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJso
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventDataJsonSerializerTest {
protected final UUID expectedId = UUID.randomUUID();
@@ -36,11 +36,11 @@ import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.ImageDescriptorImpl;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.media.VideoDescriptorImpl;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
import com.sap.sse.shared.media.impl.ImageDescriptorImpl;
import com.sap.sse.shared.media.impl.VideoDescriptorImpl;
public class EventDataJsonSerializerWithImagesAndVideosTest {
private final UUID expectedId = UUID.randomUUID();
@@ -32,8 +32,8 @@ import com.sap.sailing.server.gateway.serialization.impl.LeaderboardGroupBaseJso
import com.sap.sailing.server.gateway.serialization.impl.VenueJsonSerializer;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventDataJsonSerializerWithNullValuesTest {
protected final UUID expectedId = UUID.randomUUID();
@@ -31,8 +31,8 @@ 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;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class EventWithNullStartAndEndDataJsonSerializerTest {
@@ -70,7 +70,7 @@ public class TrackRaceBoatCompetitorMetadataReplicationTest extends AbstractServ
trackingParams = com.sap.sailing.domain.tractracadapter.DomainFactory.INSTANCE
.createTrackingConnectivityParameters(paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, /* delayToLiveInMillis */
0l, /* simulateWithStartTimeNow */false, /*ignoreTracTracMarkPassings*/ false, EmptyRaceLogStore.INSTANCE,
0l, /* offsetToStartTimeOfSimulatedRace */null, /*ignoreTracTracMarkPassings*/ false, EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, tracTracUsername, tracTracPassword, "", "");
}
@@ -88,7 +88,7 @@ public class TrackRaceReplicationTest extends AbstractServerReplicationTest {
trackingParams = com.sap.sailing.domain.tractracadapter.DomainFactory.INSTANCE
.createTrackingConnectivityParameters(paramURL, liveURI, storedURI, courseDesignUpdateURI,
startOfTracking, endOfTracking, /* delayToLiveInMillis */
0l, /* simulateWithStartTimeNow */false, /*ignoreTracTracMarkPassings*/ false, EmptyRaceLogStore.INSTANCE,
0l, /* offsetToStartTimeOfSimulatedRace */null, /*ignoreTracTracMarkPassings*/ false, EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, tracTracUsername, tracTracPassword, "", "");
}
@@ -129,11 +129,11 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.mongodb.MongoDBService;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class MasterDataImportTest {
@@ -72,10 +72,10 @@ import com.sap.sse.common.Color;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
import com.sap.sse.common.search.KeywordQuery;
import com.sap.sse.common.search.Result;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class SearchServiceTest {
private RacingEventService server;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,70 +1,70 @@
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
/**
* Creates an {@link Event} in the server, with a new venue and an empty course area list.
* See the {@link AddCourseAreas} operation for adding course areas to the event's venue.
*
* @author Axel Uhl (d043530)
*
*/
public class CreateEvent extends AbstractEventOperation<Event> {
private static final long serialVersionUID = 308389324918359960L;
private final String venue;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final String eventName;
private final String eventDescription;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
public CreateEvent(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate, String venue,
boolean isPublic, UUID id, URL officialWebsiteURL, URL sailorsInfoWebsiteURL, Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venue = venue;
this.isPublic = isPublic;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
protected String getEventName() {
return eventName;
}
@Override
public Event internalApplyTo(RacingEventService toState) {
return toState.createEventWithoutReplication(getEventName(), eventDescription, startDate, endDate, venue, isPublic,
getId(), officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
}
}
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
/**
* Creates an {@link Event} in the server, with a new venue and an empty course area list.
* See the {@link AddCourseAreas} operation for adding course areas to the event's venue.
*
* @author Axel Uhl (d043530)
*
*/
public class CreateEvent extends AbstractEventOperation<Event> {
private static final long serialVersionUID = 308389324918359960L;
private final String venue;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final String eventName;
private final String eventDescription;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
public CreateEvent(String eventName, String eventDescription, TimePoint startDate, TimePoint endDate, String venue,
boolean isPublic, UUID id, URL officialWebsiteURL, URL sailorsInfoWebsiteURL, Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venue = venue;
this.isPublic = isPublic;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
protected String getEventName() {
return eventName;
}
@Override
public Event internalApplyTo(RacingEventService toState) {
return toState.createEventWithoutReplication(getEventName(), eventDescription, startDate, endDate, venue, isPublic,
getId(), officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
}
}
@@ -1,61 +1,61 @@
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.ImageDescriptor;
import com.sap.sse.common.media.VideoDescriptor;
public class UpdateEvent extends AbstractEventOperation<Void> {
private static final long serialVersionUID = -8271559266421161532L;
private final String venueName;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final Iterable<UUID> leaderboardGroupIds;
private final String eventName;
private final String eventDescription;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
public UpdateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL, URL sailorsInfoWebsiteURL,
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venueName = venueName;
this.isPublic = isPublic;
this.leaderboardGroupIds = leaderboardGroupIds;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public Void internalApplyTo(RacingEventService toState) {
toState.updateEvent(getId(), eventName, eventDescription, startDate, endDate, venueName, isPublic,
leaderboardGroupIds, officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
return null;
}
}
package com.sap.sailing.server.operationaltransformation;
import java.net.URL;
import java.util.UUID;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
import com.sap.sse.common.TimePoint;
import com.sap.sse.shared.media.ImageDescriptor;
import com.sap.sse.shared.media.VideoDescriptor;
public class UpdateEvent extends AbstractEventOperation<Void> {
private static final long serialVersionUID = -8271559266421161532L;
private final String venueName;
private final TimePoint startDate;
private final TimePoint endDate;
private final boolean isPublic;
private final Iterable<UUID> leaderboardGroupIds;
private final String eventName;
private final String eventDescription;
private final URL officialWebsiteURL;
private final URL sailorsInfoWebsiteURL;
private final Iterable<ImageDescriptor> images;
private final Iterable<VideoDescriptor> videos;
public UpdateEvent(UUID id, String eventName, String eventDescription, TimePoint startDate, TimePoint endDate,
String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, URL officialWebsiteURL, URL sailorsInfoWebsiteURL,
Iterable<ImageDescriptor> images, Iterable<VideoDescriptor> videos) {
super(id);
this.eventName = eventName;
this.eventDescription = eventDescription;
this.startDate = startDate;
this.endDate = endDate;
this.venueName = venueName;
this.isPublic = isPublic;
this.leaderboardGroupIds = leaderboardGroupIds;
this.officialWebsiteURL = officialWebsiteURL;
this.sailorsInfoWebsiteURL = sailorsInfoWebsiteURL;
this.images = images;
this.videos = videos;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public Void internalApplyTo(RacingEventService toState) {
toState.updateEvent(getId(), eventName, eventDescription, startDate, endDate, venueName, isPublic,
leaderboardGroupIds, officialWebsiteURL, sailorsInfoWebsiteURL, images, videos);
return null;
}
}
+25 -25
View File
@@ -11,30 +11,30 @@
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
+28 -28
View File
@@ -1,31 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.datamining.annotations</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.datamining.annotations</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -7,6 +7,9 @@ import com.google.gwt.text.client.IntegerParser;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.user.client.ui.ValueBox;
/**
* Renders integers in their box without any separators, non-localized, plain.
*/
public class IntegerBox extends ValueBox<Integer> {
private static final Renderer<Integer> RENDERER = new Renderer<Integer>() {
public String render(Integer object) {
+32 -32
View File
@@ -1,32 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.security.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sse.security.common</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -7,4 +7,6 @@ Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.sap.sse.common
Export-Package: com.sap.sse.concurrent,
com.sap.sse.shared.media,
com.sap.sse.shared.media.impl,
com.sap.sse.util.impl
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import com.sap.sse.common.Util.Pair;
@@ -1,10 +1,11 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.io.Serializable;
import java.net.URL;
import java.util.Locale;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.MimeType;
/**
* A common media interface for all kinds of media like images or videos.
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.io.IOException;
import java.net.URL;
@@ -18,6 +18,7 @@ import javax.imageio.stream.ImageInputStream;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.MimeType;
public class MediaUtils {
private static final Logger logger = Logger.getLogger(MediaUtils.class.getName());
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.net.URL;
@@ -1,4 +1,5 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
public interface WithImages {
/**
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
import java.util.List;
@@ -1,4 +1,5 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media;
public interface WithVideos {
@@ -1,4 +1,4 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media.impl;
import java.io.Serializable;
import java.net.URL;
@@ -8,6 +8,8 @@ import java.util.Set;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.shared.media.MediaDescriptor;
/**
* Common media data for media items
@@ -1,9 +1,11 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media.impl;
import java.net.URL;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.shared.media.ImageDescriptor;
public class ImageDescriptorImpl extends AbstractMediaDescriptor implements ImageDescriptor {
@@ -1,8 +1,10 @@
package com.sap.sse.common.media;
package com.sap.sse.shared.media.impl;
import java.net.URL;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.media.MimeType;
import com.sap.sse.shared.media.VideoDescriptor;
public class VideoDescriptorImpl extends AbstractMediaDescriptor implements VideoDescriptor {
private static final long serialVersionUID = 2651747912466590862L;
@@ -3,6 +3,8 @@ package com.sap.sse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A class providing static information about the running server.
@@ -10,14 +12,16 @@ import java.io.FileReader;
*
*/
public class ServerInfo {
private static final Logger logger = Logger.getLogger(ServerInfo.class.getName());
public static String getBuildVersion() {
String version = "Unknown or Development (" + ServerStartupConstants.SERVER_NAME + ")";
File versionfile = new File(ServerStartupConstants.JETTY_HOME + File.separator + "version.txt");
if (versionfile.exists()) {
try {
version = new BufferedReader(new FileReader(versionfile)).readLine();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(versionfile))) {
version = bufferedReader.readLine();
} catch (Exception ex) {
/* ignore */
logger.log(Level.WARNING, "Error trying to obtain version info", ex);
}
}
return version;
@@ -0,0 +1,34 @@
package com.sap.sse.util;
import java.io.Serializable;
/**
* Implements {@link Object#equals(Object)} and {@link Object#hashCode()} based on the wrapped object's
* identity, no matter what the object itself defines as {@code equals} and {@code hashCode}.
*
* @author Axel Uhl (D043530)
*
*/
public class IdentityWrapper<T> implements Serializable {
private static final long serialVersionUID = 3514488568026067341L;
private final T t;
public IdentityWrapper(T t) {
this.t = t;
}
@Override
public int hashCode() {
return System.identityHashCode(t);
}
@Override
public boolean equals(Object obj) {
return (obj instanceof IdentityWrapper<?>) ? ((IdentityWrapper<?>) obj).t == this.t : obj == t;
}
@Override
public String toString() {
return "IdentityWrapper for "+t;
}
}
+40 -40
View File
@@ -1,40 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.json.simple</artifactId>
<version>1.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.json.simple</artifactId>
<version>1.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
+11 -11
View File
@@ -134,8 +134,8 @@
<module>com.sap.sailing.autoload</module>
<module>com.sap.sailing.feature.p2build</module>
<module>com.sap.sailing.polars</module>
<module>com.sap.sailing.polars.datamining</module>
<module>com.sap.sailing.polars.datamining.shared</module>
<module>com.sap.sailing.polars.datamining</module>
<module>com.sap.sailing.polars.datamining.shared</module>
<module>com.sap.sailing.polars.test</module>
<!--
com.sap.sailing.targetplatform.base
@@ -264,15 +264,15 @@
<version>${tycho-version}</version>
<configuration>
<resolver>p2</resolver>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>com.google.gwt.dev</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>com.google.gwt.dev</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
<target>
<artifact>
<groupId>${project.groupId}</groupId>
@@ -31,7 +31,7 @@
<Arg name="threadpool">
<New id="threadpool" class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Arg name="minThreads" type="int">10</Arg>
<Arg name="maxThreads" type="int">3000</Arg>
<Arg name="maxThreads" type="int">64</Arg>
<Arg name="idleTimeout" type="int">25000</Arg>
<Set name="detailedDump">false</Set>
</New>