Merge branch 'master' into bug2589

This commit is contained in:
Axel Uhl committed 2015-02-15 17:42:22 +01:00
commit 559d2d25ed
210 files changed
+3086 -1341

No files matched your search

@@ -22,6 +22,10 @@ public interface CompetitorDTO extends Serializable, MappableToDevice {
String getName();
Color getColor();
String getEmail();
boolean hasEmail();
/**
* A regular instance will simply return this object. A compacted version may compute the result by looking it up
@@ -19,16 +19,18 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial
private String twoLetterIsoCountryCode;
private String threeLetterIocCountryCode;
private Color color;
private String email;
private String sailID;
private String idAsString;
private BoatClassDTO boatClass;
public CompetitorDTOImpl() {}
public CompetitorDTOImpl(String name, Color color, String twoLetterIsoCountryCode, String threeLetterIocCountryCode,
public CompetitorDTOImpl(String name, Color color, String email, String twoLetterIsoCountryCode, String threeLetterIocCountryCode,
String countryName, String sailID, String idAsString, BoatClassDTO boatClass) {
super(name);
this.color = color;
this.email = email;
this.twoLetterIsoCountryCode = twoLetterIsoCountryCode;
this.threeLetterIocCountryCode = threeLetterIocCountryCode;
this.countryName = countryName;
@@ -45,6 +47,7 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial
result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode());
result = prime * result + ((sailID == null) ? 0 : sailID.hashCode());
result = prime * result + ((color == null) ? 0 : color.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + ((threeLetterIocCountryCode == null) ? 0 : threeLetterIocCountryCode.hashCode());
return result;
}
@@ -83,6 +86,11 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial
return false;
} else if (!color.equals(other.color))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
return true;
}
@@ -124,4 +132,17 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial
public Color getColor() {
return color;
}
public String getEmail() {
return email;
}
public String email(){
return email;
}
@Override
public boolean hasEmail() {
return email != null && !email.isEmpty();
}
}
@@ -92,9 +92,20 @@ public class PreviousCompetitorDTOImpl implements CompetitorDTO {
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
}
@Override
public String getEmail() {
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
}
@Override
public CompetitorDTO getCompetitorFromPrevious(LeaderboardDTO previousVersion) {
return previousVersion.competitors.get(indexInPreviousCompetitorList);
}
@Override
public boolean hasEmail() {
return false;
}
}
@@ -1,5 +1,8 @@
package com.sap.sailing.domain.common.racelog.tracking;
import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
import com.sap.sse.common.util.UrlHelper;
/**
* Shared between GWT and Android. Used for creating and deciphering the URL encoded by the QRCode, which gives the
* tracking app all necessary information for creating the device mapping of either the race or leaderboard/regatta.
@@ -13,28 +16,50 @@ package com.sap.sailing.domain.common.racelog.tracking;
*
* @author Fredrik Teschke
*/
public interface DeviceMappingConstants {
public class DeviceMappingConstants {
// According to the HTTP protocol definition (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.3), only
// schema and host are case insensitive.
// But to adhere to best practices, and due to the deficiencies of some web servers and clients,
// all URL components should be treated as case insensitive, preferring _underscores_ to CamelCase.
static final String URL_BASE = "/tracking/checkin";
static final String URL_EVENT_ID = "event_id";
static final String URL_LEADERBOARD_NAME = "leaderboard_name";
static final String URL_COMPETITOR_ID_AS_STRING = "competitor_id";
static final String URL_MARK_ID_AS_STRING = "mark_id";
static final String URL_FROM_MILLIS = "from_millis";
static final String URL_TO_MILLIS = "to_millis";
public static final String URL_BASE = "/tracking/checkin";
public static final String URL_EVENT_ID = "event_id";
public static final String URL_LEADERBOARD_NAME = "leaderboard_name";
public static final String URL_COMPETITOR_ID_AS_STRING = "competitor_id";
public static final String URL_MARK_ID_AS_STRING = "mark_id";
public static final String URL_FROM_MILLIS = "from_millis";
public static final String URL_TO_MILLIS = "to_millis";
static final String JSON_COMPETITOR_ID_AS_STRING = "competitorId";
static final String JSON_MARK_ID_AS_STRING = "markId";
static final String JSON_DEVICE_UUID = "deviceUuid";
static final String JSON_DEVICE_TYPE = "deviceType";
static final String JSON_PUSH_DEVICE_ID = "pushDeviceId";
static final String JSON_FROM_MILLIS = "fromMillis";
static final String JSON_TO_MILLIS = "toMillis";
static final String JSON_TEAM_IMAGE_URI = "teamImageUri";
public static final String JSON_COMPETITOR_ID_AS_STRING = "competitorId";
public static final String JSON_MARK_ID_AS_STRING = "markId";
public static final String JSON_DEVICE_UUID = "deviceUuid";
public static final String JSON_DEVICE_TYPE = "deviceType";
public static final String JSON_PUSH_DEVICE_ID = "pushDeviceId";
public static final String JSON_FROM_MILLIS = "fromMillis";
public static final String JSON_TO_MILLIS = "toMillis";
public static final String JSON_TEAM_IMAGE_URI = "teamImageUri";
@Deprecated
static final String APK_PATH = "/apps/com.sap.sailing.android.tracking.app.apk";
public static String getDeviceMappingForRegattaLogUrl(String serverUrlWithoutTrailingSlash, String eventId,
String leaderboardName, String mappedItemType, String mappedItemId, UrlHelper helper) {
return helper.encodeUrl(serverUrlWithoutTrailingSlash + URL_BASE + "?" + URL_EVENT_ID + "=" + eventId + "&"
+ URL_LEADERBOARD_NAME + "=" + leaderboardName + "&" + mappedItemType + "="
+ mappedItemId);
}
@Deprecated
public static String getDeviceMappingForRaceLogUrl(String serverUrlWithoutTrailingSlash, String leaderboardName,
String raceColumnName, String fleetName, String mappedItemType, String mappedItemId, long fromMillis,
long toMillis, UrlHelper helper) throws QRCodeURLCreationException {
if (fromMillis > toMillis) {
throw new QRCodeURLCreationException("from can't lie after to");
}
return helper.encodeUrl(serverUrlWithoutTrailingSlash + DeviceMappingConstants.APK_PATH + "?"
+ RaceLogServletConstants.PARAMS_LEADERBOARD_NAME + "=" + leaderboardName + "&"
+ RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME + "=" + raceColumnName + "&"
+ RaceLogServletConstants.PARAMS_RACE_FLEET_NAME + "=" + fleetName + "&" + mappedItemType + "="
+ mappedItemId + "&" + DeviceMappingConstants.URL_FROM_MILLIS + "=" + fromMillis + "&"
+ DeviceMappingConstants.URL_TO_MILLIS + "=" + toMillis);
}
}
@@ -0,0 +1,9 @@
package com.sap.sailing.domain.common.racelog.tracking;
public class QRCodeURLCreationException extends Exception {
private static final long serialVersionUID = -8243995470804772458L;
public QRCodeURLCreationException(String message) {
super(message);
}
}
@@ -40,7 +40,7 @@ public class AbstractGPSFixStoreTest {
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
protected RaceLog raceLog;
protected GPSFixStore store;
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null);
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null);
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
private final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
@@ -168,7 +168,7 @@ public class CreateAndTrackWithRaceLogTest {
assertFalse(raceLog.isEmpty());
// add a mapping and one fix in, one out of mapping
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null);
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null, null);
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
raceLog.add(factory.createDeviceCompetitorMappingEvent(t(), author, dev1, comp1, 0, t(0), t(10)));
addFixes0(dev1);
@@ -202,7 +202,7 @@ public class CreateAndTrackWithRaceLogTest {
adapter.denoteRaceForRaceLogTracking(service, leaderboard, column, fleet, "race");
// add a mapping and one fix in, one out of mapping
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null);
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null, null);
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), author, t(), UUID.randomUUID(), comp1, dev1,
t(0), t(10)));
@@ -49,7 +49,7 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
@Test
public void areFixesStoredInDb() throws TransformationException, NoCorrespondingServiceRegisteredException,
InterruptedException {
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null);
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null);
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
DeviceIdentifier device2 = new SmartphoneImeiIdentifier("imei2");
DeviceIdentifier device3 = new SmartphoneImeiIdentifier("imei3");
@@ -2,6 +2,7 @@
<classpath>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//resources/stringmessages/TrackingStringMessages_de.properties=UTF-8
@@ -17,8 +17,13 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.common,
com.sap.sse.replication,
com.sap.sse,
com.sap.sailing.server.gateway.serialization.shared.android
Import-Package: com.mongodb,
com.sap.sailing.server.gateway.serialization.shared.android,
com.sap.sse.mail
Import-Package: com.google.zxing;version="3.1.0",
com.mongodb,
javax.mail;version="1.4.0",
javax.mail.internet;version="1.4.0",
javax.mail.util;version="1.4.0",
javax.servlet;version="2.6.0",
org.json.simple,
org.json.simple.parser,
@@ -1,4 +1,5 @@
source.. = src/
source.. = src/,\
resources/
output.. = bin/
bin.includes = META-INF/,\
.
@@ -0,0 +1,4 @@
trackingInvitationFor=Einladung zum Tracken für
scanQRCodeOrVisitUrlToRegisterAs=Scanne den QRCode oder klicke den Link mit deinem Smartphone an um dich zu registrieren als
welcomeTo=Willkommen zu
alternativelyVisitThisLink=Alternativ kannst du diesen Link anklicken
@@ -0,0 +1,4 @@
trackingInvitationFor=Tracking Invitation for
scanQRCodeOrVisitUrlToRegisterAs=Scan the following QRCode or click the link using your smartphone to register as
welcomeTo=Welcome to
alternativelyVisitThisLink=Alternatively, you can click this Link
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.racelogtracking;
import java.util.Locale;
import java.util.Set;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
@@ -10,6 +11,7 @@ import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEven
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.ControlPoint;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceColumn;
@@ -24,12 +26,14 @@ import com.sap.sailing.domain.racelogtracking.impl.RaceLogRaceTracker;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.common.mail.MailException;
public interface RaceLogTrackingAdapter {
public interface RaceLogTrackingAdapter {
/**
* Performs the necessary steps to ensure that the race is tracked (aka that a {@link TrackedRace}
* is created from the data in this {@code RaceLog}).<p>
* The following steps are performed to achieve this:
* Performs the necessary steps to ensure that the race is tracked (aka that a {@link TrackedRace} is created from
* the data in this {@code RaceLog}).
* <p>
* The following steps are performed to achieve this:
* <ul>
* <li>Is the racelog denoted for tracking? If not, throw exception.</li>
* <li>Is a {@link RaceLogRaceTracker} already listening for this racelog? If not, add one.</li>
@@ -38,7 +42,7 @@ public interface RaceLogTrackingAdapter {
*/
void startTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn, Fleet fleet)
throws NotDenotedForRaceLogTrackingException, Exception;
RaceLogTrackingState getRaceLogTrackingState(RacingEventService service, RaceColumn raceColumn, Fleet fleet);
/**
@@ -51,16 +55,15 @@ public interface RaceLogTrackingAdapter {
*
* @throws NotDenotableForRaceLogTrackingException
* Fails, if no {@link RaceLog}, or a non-empty {@link RaceLog}, or one with attached
* {@link TrackedRace} is found already in place.
* Also fails, if the {@code leaderboard} is not a {@link RegattaLeaderboard}.
* {@link TrackedRace} is found already in place. Also fails, if the {@code leaderboard} is not a
* {@link RegattaLeaderboard}.
*/
void denoteRaceForRaceLogTracking(RacingEventService service, Leaderboard leaderboard, RaceColumn raceColumn,
Fleet fleet, String raceName) throws NotDenotableForRaceLogTrackingException;
/**
* Revoke the {@link RaceLogDenoteForTrackingEvent}, and if it exists the {@link RaceLogStartTrackingEvent}.
* This does not affect existing an {@link RaceLogRaceTracker}
* or {@link TrackedRace} for this {@code RaceLog}.
* Revoke the {@link RaceLogDenoteForTrackingEvent}, and if it exists the {@link RaceLogStartTrackingEvent}. This
* does not affect existing an {@link RaceLogRaceTracker} or {@link TrackedRace} for this {@code RaceLog}.
*/
void removeDenotationForRaceLogTracking(RacingEventService service, RaceLog raceLog);
@@ -71,30 +74,35 @@ public interface RaceLogTrackingAdapter {
*/
void denoteAllRacesForRaceLogTracking(RacingEventService service, Leaderboard leaderboard)
throws NotDenotableForRaceLogTrackingException;
/**
* Add a fix to the {@link GPSFixStore}, and create a mapping with a virtual device for exactly that timepoint.
*/
void pingMark(RaceLog raceLogToAddTo, Mark mark, GPSFix gpsFix, RacingEventService service);
/**
* Duplicate the course and competitor registrations in the newest {@link RaceLogCourseDesignChangedEvent}
* in {@code from} race log to the {@code to} race logs.
* The {@link Mark}s and {@link ControlPoint}s are duplicated and not reused. This also inserts the necessary
* {@link RaceLogDefineMarkEvent}s into the {@code to} race logs.
* Duplicate the course and competitor registrations in the newest {@link RaceLogCourseDesignChangedEvent} in
* {@code from} race log to the {@code to} race logs. The {@link Mark}s and {@link ControlPoint}s are duplicated and
* not reused. This also inserts the necessary {@link RaceLogDefineMarkEvent}s into the {@code to} race logs.
*/
void copyCourseAndCompetitors(RaceLog from, Set<RaceLog> to, SharedDomainFactory baseDomainFactory,
RacingEventService service);
/**
* If not yet registered, register the competitors in {@code competitors},
* and unregister all already registered competitors not in {@code competitors}.
* If not yet registered, register the competitors in {@code competitors}, and unregister all already registered
* competitors not in {@code competitors}.
*/
void registerCompetitors(RacingEventService service, RaceLog raceLog, Set<Competitor> competitors);
/**
* If not yet registered, register the competitors in {@code competitors},
* and unregister all already registered competitors not in {@code competitors}.
* If not yet registered, register the competitors in {@code competitors}, and unregister all already registered
* competitors not in {@code competitors}.
*/
void registerCompetitors(RacingEventService service, RegattaLog regattaLog, Set<Competitor> competitors);
/**
* Invite competitors for tracking via the Tracking App by sending out emails.
*/
void inviteCompetitorsForTrackingViaEmail(Event event, Leaderboard leaderboard,
String serverUrlWithoutTrailingSlash, Set<Competitor> competitors, Locale locale) throws MailException;
}
@@ -36,6 +36,12 @@ import com.sap.sse.common.TypeBasedServiceFinder;
public class Activator implements BundleActivator {
private static final Logger logger = Logger.getLogger(Activator.class.getName());
private static BundleContext context;
public static BundleContext getContext() {
return context;
}
private Set<ServiceRegistration<?>> registrations = new HashSet<>();
@@ -53,6 +59,8 @@ public class Activator implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
Activator.context = context;
registrations.add(context.registerService(DeviceIdentifierMongoHandler.class, new SmartphoneUUIDMongoHandler(), getDict(SmartphoneUUIDIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierJsonHandler.class, new SmartphoneUUIDJsonHandler(), getDict(SmartphoneUUIDIdentifier.TYPE)));
registrations.add(context.registerService(DeviceIdentifierStringSerializationHandler.class, new SmartphoneUUIDStringSerializationHandler(), getDict(SmartphoneUUIDIdentifier.TYPE)));
@@ -75,6 +83,8 @@ public class Activator implements BundleActivator {
@Override
public void stop(BundleContext context) throws Exception {
Activator.context = null;
for (ServiceRegistration<?> reg : registrations) {
reg.unregister();
}
@@ -1,8 +1,11 @@
package com.sap.sailing.domain.racelogtracking.impl;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -10,6 +13,17 @@ import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import org.osgi.framework.ServiceReference;
import com.google.zxing.WriterException;
import com.sap.sailing.domain.abstractlog.AbstractLog;
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
@@ -32,6 +46,7 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.ControlPoint;
import com.sap.sailing.domain.base.CourseBase;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceColumn;
@@ -42,6 +57,7 @@ import com.sap.sailing.domain.base.impl.CourseDataImpl;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotableForRaceLogTrackingException;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException;
import com.sap.sailing.domain.common.racelog.tracking.RaceLogRaceTrackerExistsException;
@@ -61,6 +77,10 @@ import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.mail.MailException;
import com.sap.sse.common.qrcode.QRCodeGenerationUtil;
import com.sap.sse.mail.MailService;
import com.sap.sse.util.impl.NonGwtUrlHelper;
public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
private static final Logger logger = Logger.getLogger(RaceLogTrackingAdapterImpl.class.getName());
@@ -325,4 +345,66 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
c -> new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), service.getServerAuthor(),
MillisecondsTimePoint.now(), UUID.randomUUID(), c));
}
private MailService getMailService() {
ServiceReference<MailService> ref = Activator.getContext()
.getServiceReference(MailService.class);
if (ref == null) {
logger.warning("No file storage management service registered");
return null;
}
return Activator.getContext().getService(ref);
}
@Override
public void inviteCompetitorsForTrackingViaEmail(Event event, Leaderboard leaderboard,
String serverUrlWithoutTrailingSlash, Set<Competitor> competitors, Locale locale) throws MailException {
StringBuilder occuredExceptions = new StringBuilder();
for (Competitor competitor : competitors){
final String toAddress = competitor.getEmail();
if (toAddress != null) {
String leaderboardName = leaderboard.getName();
String competitorName = competitor.getName();
String url = DeviceMappingConstants.getDeviceMappingForRegattaLogUrl(serverUrlWithoutTrailingSlash,
event.getId().toString(), leaderboardName, DeviceMappingConstants.URL_COMPETITOR_ID_AS_STRING,
competitor.getId().toString(), NonGwtUrlHelper.INSTANCE);
String subject = String.format("%s %s",
RaceLogTrackingI18n.STRING_MESSAGES.get(locale, "trackingInvitationFor"), competitorName);
// taken from http://www.tutorialspoint.com/javamail_api/javamail_api_send_inlineimage_in_email.htm
BodyPart messageTextPart = new MimeBodyPart();
String htmlText = String.format("<h1>%s %s</h1>" + "<p>%s <b>%s</b></p>"
+ "<img src=\"cid:image\" title=\"%s\"><br/>"
+ "<a href=\"%s\">%s</a>",
RaceLogTrackingI18n.STRING_MESSAGES.get(locale, "welcomeTo"), leaderboardName,
RaceLogTrackingI18n.STRING_MESSAGES.get(locale, "scanQRCodeOrVisitUrlToRegisterAs"), competitorName,
url, url, RaceLogTrackingI18n.STRING_MESSAGES.get(locale, "alternativelyVisitThisLink"));
try {
messageTextPart.setContent(htmlText, "text/html");
BodyPart messageImagePart = new MimeBodyPart();
InputStream imageIs = QRCodeGenerationUtil.create(url, 250);
DataSource imageDs = new ByteArrayDataSource(imageIs, "image/png");
messageImagePart.setDataHandler(new DataHandler(imageDs));
messageImagePart.setHeader("Content-ID", "<image>");
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(messageTextPart);
multipart.addBodyPart(messageImagePart);
getMailService().sendMail(toAddress, subject, multipart);
} catch (MessagingException | MailException | WriterException | IOException e) {
logger.log(Level.SEVERE, "Error trying to send mail to " + competitor.getName()
+ " with e-mail address " + toAddress, e);
occuredExceptions.append(e.getMessage()+"\r\n");
}
}
}
if (!(occuredExceptions.length() == 0)){
throw new MailException(occuredExceptions.toString());
}
}
}
@@ -0,0 +1,11 @@
package com.sap.sailing.domain.racelogtracking.impl;
import com.sap.sse.i18n.ResourceBundleStringMessages;
import com.sap.sse.i18n.impl.ResourceBundleStringMessagesImpl;
public class RaceLogTrackingI18n {
private static final String RESOURCE_BASE_NAME = "stringmessages/TrackingStringMessages";
public static final ResourceBundleStringMessages STRING_MESSAGES = new ResourceBundleStringMessagesImpl(
RESOURCE_BASE_NAME, RaceLogTrackingI18n.class.getClassLoader());
}
@@ -52,7 +52,7 @@ public class MultiLogAnalyzerTest {
private AbstractLogEventAuthor author;
private static Competitor createCompetitor(int n) {
return new CompetitorImpl(n, n + "", null, null, null);
return new CompetitorImpl(n, n + "", null, null, null, null);
}
private static DeviceIdentifier createDevice() {
@@ -22,8 +22,8 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class DeviceMappingFinderTest extends AbstractRaceLogTrackingTest {
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null);
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null);
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null, null);
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null, null);
private final DeviceIdentifier device = new SmartphoneImeiIdentifier("imei");
private int time = 0;
@@ -15,6 +15,10 @@ public interface Competitor extends Named, WithID, IsManagedByCache<SharedDomain
Color getColor();
String getEmail();
boolean hasEmail();
/**
* Adds a listener to this competitor. The listener is also added to the boat and the team for changes.
* Adding a listener that is already part of this competitor's listeners set remains without effect.
@@ -6,4 +6,6 @@ public interface CompetitorChangeListener extends BoatChangeListener, Nationalit
void colorChanged(Color oldColor, Color newColor);
void nameChanged(String oldName, String newName);
void emailChanged(String oldEmail, String newEmail);
}
@@ -26,5 +26,5 @@ public interface CompetitorFactory {
*/
boolean isCompetitorToUpdateDuringGetOrCreate(Competitor result);
Competitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, DynamicTeam team, DynamicBoat boat);
Competitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, String email, DynamicTeam team, DynamicBoat boat);
}
@@ -63,7 +63,7 @@ public interface CompetitorStore extends CompetitorFactory {
*
* If no competitor with the ID requested is found, the call is a no-op, doing nothing, not even throwing an exception.
*/
Competitor updateCompetitor(String idAsString, String newName, Color newDisplayColor, String newSailId,
Competitor updateCompetitor(String idAsString, String newName, Color newDisplayColor, String newEmail, String newSailId,
Nationality newNationality, URI newTeamImageUri);
CompetitorDTO convertToCompetitorDTO(Competitor c);
@@ -20,13 +20,15 @@ public class CompetitorImpl implements DynamicCompetitor {
private String name;
private Color color;
private transient Set<CompetitorChangeListener> listeners;
private String email;
public CompetitorImpl(Serializable id, String name, Color color, DynamicTeam team, DynamicBoat boat) {
public CompetitorImpl(Serializable id, String name, Color color, String email, DynamicTeam team, DynamicBoat boat) {
this.id = id;
this.name = name;
this.team = team;
this.boat = boat;
this.color = color;
this.email = email;
this.listeners = new HashSet<CompetitorChangeListener>();
}
@@ -73,7 +75,7 @@ public class CompetitorImpl implements DynamicCompetitor {
@Override
public Competitor resolve(SharedDomainFactory domainFactory) {
Competitor result = domainFactory.getOrCreateCompetitor(getId(), getName(), getColor(), getTeam(), getBoat());
Competitor result = domainFactory.getOrCreateCompetitor(getId(), getName(), getColor(), getEmail(), getTeam(), getBoat());
return result;
}
@@ -114,4 +116,22 @@ public class CompetitorImpl implements DynamicCompetitor {
return new HashSet<CompetitorChangeListener>(listeners);
}
}
public String getEmail() {
return email;
}
public void setEmail(String newEmail) {
final String oldEmail = this.email;
if (!Util.equalsWithNull(oldEmail, newEmail)) {
this.email = newEmail;
for (CompetitorChangeListener listener : getListeners()) {
listener.emailChanged(oldEmail, newEmail);
}
}
}
public boolean hasEmail(){
return email != null && !email.isEmpty();
}
}
@@ -6,7 +6,10 @@ import com.sap.sse.common.Color;
public interface DynamicCompetitor extends Competitor, Renamable {
DynamicBoat getBoat();
DynamicTeam getTeam();
void setColor(Color displayColor);
void setEmail(String email);
}
@@ -332,11 +332,11 @@ public class SharedDomainFactoryImpl implements SharedDomainFactory {
}
@Override
public Competitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, DynamicTeam team, DynamicBoat boat) {
public Competitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, String email, DynamicTeam team, DynamicBoat boat) {
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "getting or creating competitor "+name+" with ID "+competitorId+" in domain factory "+this);
}
return getCompetitorStore().getOrCreateCompetitor(competitorId, name, displayColor, team, boat);
return getCompetitorStore().getOrCreateCompetitor(competitorId, name, displayColor, email, team, boat);
}
@Override
@@ -68,8 +68,8 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
listeners.remove(listener);
}
private Competitor createCompetitor(Serializable id, String name, Color displayColor, DynamicTeam team, DynamicBoat boat) {
Competitor result = new CompetitorImpl(id, name, displayColor, team, boat);
private Competitor createCompetitor(Serializable id, String name, Color displayColor, String email, DynamicTeam team, DynamicBoat boat) {
Competitor result = new CompetitorImpl(id, name, displayColor, email, team, boat);
addNewCompetitor(id, result);
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "Created competitor "+name+" with ID "+id, new Exception("Here is where it happened"));
@@ -93,20 +93,20 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
}
@Override
public Competitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, DynamicTeam team, DynamicBoat boat) {
public Competitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, String email, DynamicTeam team, DynamicBoat boat) {
Competitor result = getExistingCompetitorById(competitorId); // avoid synchronization for successful read access
if (result == null) {
LockUtil.lockForWrite(lock);
try {
result = getExistingCompetitorById(competitorId); // try again, now while holding the write lock
if (result == null) {
result = createCompetitor(competitorId, name, displayColor, team, boat);
result = createCompetitor(competitorId, name, displayColor, email, team, boat);
}
} finally {
LockUtil.unlockAfterWrite(lock);
}
} else if (isCompetitorToUpdateDuringGetOrCreate(result)) {
updateCompetitor(result.getId().toString(), name, displayColor, boat.getSailID(), team.getNationality(),
updateCompetitor(result.getId().toString(), name, displayColor, email, boat.getSailID(), team.getNationality(),
team.getImage());
competitorNoLongerToUpdateDuringGetOrCreate(result);
}
@@ -191,7 +191,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
}
@Override
public Competitor updateCompetitor(String idAsString, String newName, Color newDisplayColor, String newSailId,
public Competitor updateCompetitor(String idAsString, String newName, Color newDisplayColor, String newEmail, String newSailId,
Nationality newNationality, URI newTeamImageUri) {
DynamicCompetitor competitor = (DynamicCompetitor) getExistingCompetitorByIdAsString(idAsString);
if (competitor != null) {
@@ -199,6 +199,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
try {
competitor.setName(newName);
competitor.setColor(newDisplayColor);
competitor.setEmail(newEmail);
competitor.getBoat().setSailId(newSailId);
competitor.getTeam().setNationality(newNationality);
competitor.getTeam().setImage(newTeamImageUri);
@@ -229,7 +230,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
if (competitorDTO == null) {
final Nationality nationality = c.getTeam().getNationality();
CountryCode countryCode = nationality == null ? null : nationality.getCountryCode();
competitorDTO = new CompetitorDTOImpl(c.getName(), c.getColor(), countryCode == null ? ""
competitorDTO = new CompetitorDTOImpl(c.getName(), c.getColor(), c.getEmail(), countryCode == null ? ""
: countryCode.getTwoLetterISOCode(), countryCode == null ? ""
: countryCode.getThreeLetterIOCCode(), countryCode == null ? "" : countryCode.getName(), c
.getBoat().getSailID(), c.getId().toString(), new BoatClassDTO(c.getBoat().getBoatClass()
@@ -124,7 +124,7 @@ public class DomainFactoryImpl implements DomainFactory {
teamMembers.add(person);
}
DynamicTeam team = new TeamImpl(competitor.getName(), teamMembers, /* coach */ null);
result = competitorStore.getOrCreateCompetitor(competitor.getID(), competitor.getName(), null /*displayColor*/, team, boat);
result = competitorStore.getOrCreateCompetitor(competitor.getID(), competitor.getName(), null /*displayColor*/, null /*email*/, team, boat);
}
return result;
}
@@ -140,7 +140,7 @@ public class DomainFactoryImpl implements DomainFactory {
}
DynamicTeam team = new TeamImpl(competitor.getName(), teamMembers, /* coach */ null);
result = baseDomainFactory.getCompetitorStore().getOrCreateCompetitor(getCompetitorID(competitor.getBoatID(), raceId, boatClass),
competitor.getName(), null /*displayColor*/, team, boat);
competitor.getName(), null /*displayColor*/, null /*email*/, team, boat);
return result;
}
@@ -232,7 +232,7 @@ public class LeaderboardDTODiffingTest {
@Test
public void testCompetitorListChange() {
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "DE", "GER", "Germany", "GER 1234", "912p09871203987",
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "GER 1234", "912p09871203987",
new BoatClassDTO("505", 5.05));
newVersion.competitors.add(13, somebodyNew); // insert a competitor; this should mess up all others' indexes; check if this works
CompetitorDTO wolfgang = getPreviousCompetitorByName("HUNGER +JESS");
@@ -252,7 +252,7 @@ public class LeaderboardDTODiffingTest {
Util.addAll(newVersion.getSuppressedCompetitors(), newSuppressedCompetitors);
newVersion.setSuppressedCompetitors(newSuppressedCompetitors);
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "DE", "GER", "Germany", "GER 1234", "912p09871203987",
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "GER 1234", "912p09871203987",
new BoatClassDTO("505", 5.05));
newVersion.setSuppressed(newVersion.competitors.get(13), true); // suppress an existing competitor; compaction should reduce this to a single number only
newVersion.setSuppressed(somebodyNew, true); // check that mixed mode with existing and new competitors works as well
@@ -274,7 +274,7 @@ public class LeaderboardDTODiffingTest {
@Test
public void testDisplayNameChange() {
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "DE", "GER", "Germany", "GER 1234", "912p09871203987",
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "GER 1234", "912p09871203987",
new BoatClassDTO("505", 5.05));
newVersion.competitors.add(somebodyNew);
newVersion.competitorDisplayNames = new HashMap<CompetitorDTO, String>(newVersion.competitorDisplayNames);
@@ -303,7 +303,7 @@ public class LeaderboardDTODiffingTest {
List<CompetitorDTO> newOrdering = new ArrayList<CompetitorDTO>(newVersion.getCompetitorsFromBestToWorst(r9));
newVersion.setCompetitorsFromBestToWorst(r9, newOrdering);
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "DE", "GER", "Germany", "GER 1234", "912p09871203987",
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "GER 1234", "912p09871203987",
new BoatClassDTO("505", 5.05));
newVersion.competitors.add(somebodyNew);
newOrdering.add(somebodyNew);
@@ -15,16 +15,16 @@ import com.sap.sse.common.Color;
public abstract class AbstractLeaderboardTest {
public static CompetitorImpl createCompetitor(String competitorName) {
return new CompetitorImpl(competitorName, competitorName, Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
return new CompetitorImpl(competitorName, competitorName, Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
new BoatClassImpl("505", /* typicallyStartsUpwind */ true), /* sailID */ null));
}
public static Competitor createCompetitor(String competitorName, CompetitorFactory competitorFactory) {
return competitorFactory.getOrCreateCompetitor(competitorName, competitorName, Color.RED, new TeamImpl("STG", Collections.singleton(
return competitorFactory.getOrCreateCompetitor(competitorName, competitorName, Color.RED, "someone@nobody.de", new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
@@ -33,11 +33,11 @@ public abstract class AbstractLeaderboardTest {
}
public static CompetitorImpl createCompetitor(String competitorName, Serializable id) {
return new CompetitorImpl(id, competitorName, Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
return new CompetitorImpl(id, competitorName, Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
new BoatClassImpl("505", /* typicallyStartsUpwind */ true), /* sailID */ null));
}
}
@@ -94,6 +94,11 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
CompetitorListenerTest.this.oldColor = oldColor;
CompetitorListenerTest.this.newColor = newColor;
}
@Override
public void emailChanged(String oldEmail, String newEmail) {
//TODO
}
};
competitor.addCompetitorChangeListener(listener);
}
@@ -157,8 +157,8 @@ public class LeaderboardCourseChangeTest {
Set<Competitor> competitors = new HashSet<>();
DynamicBoat mockedBoat = mock(DynamicBoat.class);
when(mockedBoat.getBoatClass()).thenReturn(boatClass);
competitors.add(new CompetitorImpl(UUID.randomUUID(), "TestCompetitor", Color.BLACK, mock(DynamicTeam.class),
mockedBoat));
competitors.add(new CompetitorImpl(UUID.randomUUID(), "TestCompetitor", Color.BLACK, null,
mock(DynamicTeam.class), mockedBoat));
return competitors;
}
@@ -188,11 +188,11 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
DomainFactory senderDomainFactory = new DomainFactoryImpl();
DomainFactory receiverDomainFactory = new DomainFactoryImpl();
String competitorName = "Tina Maximiliane Lutz";
Competitor sendersCompetitor1 = new CompetitorImpl(123, competitorName, Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, senderDomainFactory.getOrCreateNationality("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", senderDomainFactory.getOrCreateNationality("GER"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
Competitor sendersCompetitor1 = new CompetitorImpl(123, competitorName, Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, senderDomainFactory.getOrCreateNationality("GER"),
/* dateOfBirth */ null, "This is famous "+competitorName)),
new PersonImpl("Rigo van Maas", senderDomainFactory.getOrCreateNationality("GER"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
senderDomainFactory.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true), "GER 61"));
Competitor receiversCompetitor1 = cloneBySerialization(sendersCompetitor1, receiverDomainFactory);
Competitor receiversSecondCopyOfCompetitor1 = cloneBySerialization(sendersCompetitor1, receiverDomainFactory);
@@ -117,7 +117,7 @@ public abstract class StoredTrackBasedTest extends TrackBasedTest {
for (String competitorName : getCompetitorNamesOfStoredTracks(KIELER_WOCHE)) {
DynamicPerson p = new PersonImpl(competitorName, /* nationality */ null, /* dateOfBirth */ null, /* description */ null);
DynamicTeam t = new TeamImpl(competitorName, Collections.singleton(p), /* coach */ null);
Competitor c = new CompetitorImpl(competitorName, competitorName, Color.RED, t, new BoatImpl(competitorName,
Competitor c = new CompetitorImpl(competitorName, competitorName, Color.RED, null, t, new BoatImpl(competitorName,
new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = readTrack(c, KIELER_WOCHE);
if (track != null) {
@@ -34,11 +34,11 @@ public class TackTest extends StoredTrackBasedTestWithTrackedRace {
@Override
@Before
public void setUp() {
competitor = new CompetitorImpl(123, "Wolfgang Hunger", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Wolfgang Hunger", new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous Wolfgang Hunger")), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl("Wolfgang Hunger's boat",
competitor = new CompetitorImpl(123, "Wolfgang Hunger", Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Wolfgang Hunger", new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous Wolfgang Hunger")), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl("Wolfgang Hunger's boat",
new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
setTrackedRace(createTestTrackedRace("Kieler Woche", "505 Race 2", "505", Collections.singleton(competitor),
new MillisecondsTimePoint(new GregorianCalendar(2011, 05, 23).getTime())));
@@ -60,11 +60,11 @@ public abstract class TrackBasedTest {
}
public static CompetitorImpl createCompetitor(String competitorName) {
return new CompetitorImpl(UUID.randomUUID(), competitorName, Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous " + competitorName)), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
return new CompetitorImpl(UUID.randomUUID(), competitorName, Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl(competitorName, new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous " + competitorName)), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl(competitorName + "'s boat",
new BoatClassImpl("505", /* typicallyStartsUpwind */true), null));
}
@@ -270,11 +270,11 @@ public class WindTest {
Waypoint w1 = domainFactory.createWaypoint(startFinish, /*passingInstruction*/ null);
Waypoint w2 = domainFactory.createWaypoint(top, /*passingInstruction*/ null);
Waypoint w3 = domainFactory.createWaypoint(startFinish, /*passingInstruction*/ null);
Competitor competitor = new CompetitorImpl(123, "Test Competitor", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Test Competitor", new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous " + "Test Competitor")), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl("Test Competitor" + "'s boat",
Competitor competitor = new CompetitorImpl(123, "Test Competitor", Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Test Competitor", new NationalityImpl("GER"),
/* dateOfBirth */null, "This is famous " + "Test Competitor")), new PersonImpl("Rigo van Maas",
new NationalityImpl("NED"),
/* dateOfBirth */null, "This is Rigo, the coach")), new BoatImpl("Test Competitor" + "'s boat",
new BoatClassImpl("505", /* typicallyStartsUpwind */true), null));
final BoatClass boatClass = domainFactory.getOrCreateBoatClass("ESS40");
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(
@@ -45,9 +45,9 @@ import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class AbstractMockedRaceMarkPassingTest {
protected Competitor bob = new CompetitorImpl("Bob", "Bob", null, null, null);
protected Competitor joe = new CompetitorImpl("Joe", "Joe", null, null, null);
protected Competitor mike = new CompetitorImpl("Mike", "Mike", null, null, null);
protected Competitor bob = new CompetitorImpl("Bob", "Bob", null, null, null, null);
protected Competitor joe = new CompetitorImpl("Joe", "Joe", null, null, null, null);
protected Competitor mike = new CompetitorImpl("Mike", "Mike", null, null, null, null);
protected Mark m = new MarkImpl("black");
protected Mark m2 = new MarkImpl("white 1");
@@ -291,7 +291,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Iterable<Competitor> getCompetitors() {
public Iterable<Competitor> getAllCompetitors() {
return null;
}
@@ -259,7 +259,7 @@ public class DomainFactoryImpl implements DomainFactory {
}
DynamicTeam team = getOrCreateTeam(name, nationality, competitorId);
DynamicBoat boat = new BoatImpl(shortName, boatClass, shortName);
result = competitorStore.getOrCreateCompetitor(competitorId, name, null /*displayColor*/, team, boat);
result = competitorStore.getOrCreateCompetitor(competitorId, name, null /*displayColor*/, null /*email*/, team, boat);
}
return result;
}
@@ -103,7 +103,7 @@ public interface Regatta extends Named, WithID, IsRegattaLike {
BoatClass getBoatClass();
Iterable<Competitor> getCompetitors();
Iterable<Competitor> getAllCompetitors();
/**
* Will remove the series from this regatta. Will also call {@link RaceColumn#removeRaceIdentifier(Fleet)} to make
@@ -10,7 +10,7 @@ public interface DynamicCompetitorStore extends CompetitorStore {
DynamicCompetitor getExistingCompetitorById(Serializable competitorId);
@Override
DynamicCompetitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, DynamicTeam team, DynamicBoat boat);
DynamicCompetitor getOrCreateCompetitor(Serializable competitorId, String name, Color displayColor, String email, DynamicTeam team, DynamicBoat boat);
@Override
Iterable<? extends DynamicCompetitor> getCompetitors();
@@ -12,6 +12,7 @@ import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
@@ -299,13 +300,26 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
}
@Override
public Iterable<Competitor> getCompetitors() {
public Iterable<Competitor> getAllCompetitors() {
Set<Competitor> result = new HashSet<Competitor>();
for (RaceDefinition race : getAllRaces()) {
for (Competitor c : race.getCompetitors()) {
result.add(c);
}
}
for (Series series : getSeries()) {
for (RaceColumn rc : series.getRaceColumns()) {
for (Fleet fleet : rc.getFleets()) {
TrackedRace trackedRace = rc.getTrackedRace(fleet);
if (trackedRace != null) {
Util.addAll(trackedRace.getRace().getCompetitors(), result);
}
}
}
}
//consider {@link RegattaLog}
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(regattaLikeHelper.getRegattaLog()).analyze();
result.addAll(viaLog);
return result;
}
@@ -88,7 +88,9 @@ public interface Leaderboard extends LeaderboardBase {
* in a regular view of the leaderboard. Editors for leaderboards shall, though, also display the suppressed competitors
* together with a visual indication showing which competitors are currently suppressed. The "suppressed-state" of a
* competitor can change over the life cycle of a leaderboard. A typical use case for suppressing a competitor is
* removing one-time entries from a series (meta-)leaderboard or suppressing a camera boat in scoring.
* removing one-time entries from a series (meta-)leaderboard or suppressing a camera boat in scoring.<p>
*
* @return all competitors in this leaderboard, including the suppressed ones.
*/
Iterable<Competitor> getAllCompetitors();
@@ -116,6 +116,11 @@ public class LeaderboardCacheManager {
competitor.removeCompetitorChangeListener(this);
}
}
@Override
public void emailChanged(String oldEmail, String newEmail) {
//ignore (email not shown in leaderboard)
}
}
@@ -70,6 +70,10 @@ public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardI
return Collections.unmodifiableSet(trackedRaces);
}
/**
* This default implementation collects all competitors by visiting all {@link TrackedRace}s associated with this
* leaderboard's columns (see {@link #getTrackedRaces()}).
*/
@Override
public Iterable<Competitor> getAllCompetitors() {
if (allCompetitorsCache == null) {
@@ -6,10 +6,14 @@ import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.shared.analyzing.RegisteredCompetitorsAnalyzer;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
@@ -275,4 +279,16 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
public void removeListener(RegattaLikeListener listener) {
regattaLikeHelper.removeListener(listener);
}
@Override
public Iterable<Competitor> getAllCompetitors() {
Set<Competitor> result = new HashSet<>();
for (Competitor c : super.getAllCompetitors()) {
result.add(c);
}
//consider {@link RegattaLog}
Set<Competitor> viaLog = new RegisteredCompetitorsAnalyzer<>(regattaLikeHelper.getRegattaLog()).analyze();
result.addAll(viaLog);
return result;
}
}
@@ -3,11 +3,14 @@ package com.sap.sailing.domain.leaderboard.impl;
import java.util.ArrayList;
import java.util.List;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceColumnInSeries;
import com.sap.sailing.domain.base.RaceColumnListener;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.RaceColumnInSeriesImpl;
@@ -96,6 +99,17 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
}
}
/**
* Delegates to {@link Regatta#getAllCompetitors()} which is expected to deliver all competitors from this
* leaderboard's regatta which includes those belonging to {@link RaceDefinition races}
* {@link Regatta#getAllRaces() belonging to the regatta} as well as competitors listed on the regatta's
* {@link RegattaLog}.
*/
@Override
public Iterable<Competitor> getAllCompetitors() {
return regatta.getAllCompetitors();
}
@Override
public IsRegattaLike getRegattaLike() {
return regatta;
@@ -72,6 +72,16 @@ public class DummyMarkPassingWithTimePointOnly implements MarkPassing {
@Override
public void removeCompetitorChangeListener(CompetitorChangeListener listener) {
}
@Override
public String getEmail() {
return null;
}
@Override
public boolean hasEmail() {
return false;
}
};
}
}
+415 -401
View File
@@ -9,392 +9,392 @@
The SAP Sailing Server.
Provides connectivity to a TracTrac live GPS feed as well as a live feed from an Expedition system.
Computes leaderboard information for sailing races and offers RESTful APIs to all of this.
</description>
<copyright url="http://www.example.com/copyright">
[Enter Copyright Description here.]
</copyright>
<license url="http://www.example.com/license">
[Enter License Description here.]
</license>
<requires>
<import plugin="com.googlecode.java-diff-utils" version="1.3.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi" version="3.10.1" match="greaterOrEqual"/>
<import plugin="javax.servlet" version="3.1.0" match="greaterOrEqual"/>
<import plugin="com.mongodb.driver" version="2.6.2" match="greaterOrEqual"/>
<import plugin="com.google.gwt.osgi" version="2.6.1" match="greaterOrEqual"/>
<import plugin="org.json.simple" version="1.1.0" match="greaterOrEqual"/>
<import plugin="org.moxieapps.gwt.highcharts" version="1.1.4" match="greaterOrEqual"/>
<import plugin="org.apache.geronimo.specs.geronimo-jms_1.1_spec"/>
<import plugin="com.rabbitmq.client"/>
<import plugin="org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec"/>
</requires>
<plugin
id="com.sap.sailing.geocoding"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.tractracadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.expeditionconnector"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway.ess40"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.tractrac.clientmodule"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.declination"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.swisstimingadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.swisstimingadapter.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.swisstimingreplayadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.tractracadapter.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.gwt"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.security"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.security.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.security.userstore.mongodb"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.gwt.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.udpconnector"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.xmlexport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.simulator"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.www"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.sap.sailing.www.events"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.sap.sailing.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.kiworesultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.ess40.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.freg.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.barbados.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.sailwave.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.manage2sail.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.velum.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.monitoring"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.xrr.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.igtimiadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.igtimiadapter.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.racelogtrackingadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.deckmanadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.autoload"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.datamining"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.datamining.shared"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.gateway"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.gwt.adminconsole"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.mongodb"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.operationaltransformation"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.replication"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.xrr.structureimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway.serialization.shared.android"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway.serialization"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
Computes leaderboard information for sailing races and offers RESTful APIs to all of this.
</description>
<copyright url="http://www.example.com/copyright">
[Enter Copyright Description here.]
</copyright>
<license url="http://www.example.com/license">
[Enter License Description here.]
</license>
<requires>
<import plugin="com.googlecode.java-diff-utils" version="1.3.0" match="greaterOrEqual"/>
<import plugin="org.eclipse.osgi" version="3.10.1" match="greaterOrEqual"/>
<import plugin="javax.servlet" version="3.1.0" match="greaterOrEqual"/>
<import plugin="com.mongodb.driver" version="2.6.2" match="greaterOrEqual"/>
<import plugin="com.google.gwt.osgi" version="2.6.1" match="greaterOrEqual"/>
<import plugin="org.json.simple" version="1.1.0" match="greaterOrEqual"/>
<import plugin="org.moxieapps.gwt.highcharts" version="1.1.4" match="greaterOrEqual"/>
<import plugin="org.apache.geronimo.specs.geronimo-jms_1.1_spec"/>
<import plugin="com.rabbitmq.client"/>
<import plugin="org.apache.geronimo.specs.geronimo-j2ee-management_1.1_spec"/>
</requires>
<plugin
id="com.sap.sailing.geocoding"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.tractracadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.expeditionconnector"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway.ess40"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.tractrac.clientmodule"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.declination"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.swisstimingadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.swisstimingadapter.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.swisstimingreplayadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.tractracadapter.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.gwt"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.security"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.security.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.security.userstore.mongodb"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.gwt.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.udpconnector"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.xmlexport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.simulator"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.www"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.sap.sailing.www.events"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="com.sap.sailing.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.kiworesultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.ess40.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.freg.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.barbados.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.sailwave.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.manage2sail.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.velum.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.monitoring"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.xrr.resultimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.igtimiadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.igtimiadapter.persistence"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.racelogtrackingadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.domain.deckmanadapter"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.autoload"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.datamining"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.datamining.shared"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.gateway"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.gwt.adminconsole"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.mongodb"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.operationaltransformation"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.replication"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.xrr.structureimport"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway.serialization.shared.android"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.server.gateway.serialization"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.filestorage"
download-size="0"
@@ -402,18 +402,32 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.shared.android"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.dashboards.gwt"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>
<plugin
id="com.sap.sse.shared.android"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.dashboards.gwt"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sse.mail"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.dashboards.gwt"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>
@@ -336,7 +336,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Iterable<Competitor> getCompetitors() {
public Iterable<Competitor> getAllCompetitors() {
// TODO Auto-generated method stub
return null;
}
@@ -163,8 +163,8 @@ public class PolarSheetGenerationServiceTest {
waypoints.add(new WaypointImpl(null));
waypoints.add(new WaypointImpl(null));
ArrayList<Competitor> competitors = new ArrayList<Competitor>();
Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", Color.RED, new TeamImpl("SAP", null, null),
new BoatImpl("Schnelle Forelle", forelle, "GER000"));
Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", Color.RED, null,
new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000"));
competitors.add(competitor);
RaceDefinition race = new RaceDefinitionImpl("Forelle1", new CourseImpl("ForelleCourse", waypoints), forelle, competitors);
return race;
@@ -1,8 +1,5 @@
package com.sap.sailing.gwt.ui.test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.net.UnknownHostException;
import java.text.ParseException;
@@ -11,9 +8,6 @@ import java.util.List;
import javax.xml.bind.JAXBException;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.common.RegattaIdentifier;
@@ -27,7 +21,6 @@ import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapter;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingAdapterFactory;
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory;
import com.sap.sailing.domain.swisstimingreplayadapter.SwissTimingReplayService;
import com.sap.sailing.domain.swisstimingreplayadapter.SwissTimingReplayServiceFactory;
import com.sap.sailing.domain.tracking.RaceHandle;
import com.sap.sailing.domain.tracking.TrackerManager;
import com.sap.sailing.domain.tractracadapter.TracTracAdapterFactory;
@@ -43,72 +36,37 @@ import com.sap.sse.replication.impl.ReplicationServiceImpl;
public class SailingServiceImplMock extends SailingServiceImpl {
private static final long serialVersionUID = 8564037671550730455L;
private RacingEventService service;
private final RacingEventService service;
private ReplicationService replicationService;
private final ScoreCorrectionProvider scoreCorrectionProvider = null;
private final TracTracAdapterFactory tracTracAdapterFactory = TracTracAdapterFactory.INSTANCE;
private final SwissTimingAdapterFactory swissTimingAdapterFactory;
private final SwissTimingReplayService swissTimingReplayService = null;
private final RaceLogTrackingAdapterFactory raceLogTrackingAdapterFactory = RaceLogTrackingAdapterFactory.INSTANCE;
public SailingServiceImplMock() {
super();
service = new RacingEventServiceImpl(true, new MockSmartphoneImeiServiceFinderFactory());
}
@Override
protected ServiceTracker<RacingEventService, RacingEventService> createAndOpenRacingEventServiceTracker(
BundleContext context) {
@SuppressWarnings("unchecked")
ServiceTracker<RacingEventService, RacingEventService> result = mock(ServiceTracker.class);
when(result.getService()).thenReturn(new RacingEventServiceImpl());
return result;
}
@Override
protected ServiceTracker<ReplicationService, ReplicationService> createAndOpenReplicationServiceTracker(
BundleContext context) {
@SuppressWarnings("unchecked")
ServiceTracker<ReplicationService, ReplicationService> result = mock(ServiceTracker.class);
try {
final RacingEventService replicable = new RacingEventServiceImpl();
final ReplicationServiceImpl replicationService =
new ReplicationServiceImpl("test exchange", "localhost", 0,
new ReplicationInstancesManager(), new AbstractReplicablesProvider() {
@Override
public Iterable<Replicable<?, ?>> getReplicables() {
return Collections.<Replicable<?, ?>>singleton(replicable);
}
});
when(result.getService()).thenReturn(replicationService);
replicationService = new ReplicationServiceImpl("test exchange", "localhost", 0,
new ReplicationInstancesManager(), new AbstractReplicablesProvider() {
@Override
public Iterable<Replicable<?, ?>> getReplicables() {
return Collections.<Replicable<?, ?>> singleton(service);
}
});
} catch (IOException e) {
throw new RuntimeException();
e.printStackTrace();
}
return result;
}
@Override
protected ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> createAndOpenScoreCorrectionProviderServiceTracker(
BundleContext bundleContext) {
return null;
}
@Override
protected ServiceTracker<TracTracAdapterFactory, TracTracAdapterFactory> createAndOpenTracTracAdapterTracker(
BundleContext context) {
@SuppressWarnings("unchecked")
ServiceTracker<TracTracAdapterFactory, TracTracAdapterFactory> result = mock(ServiceTracker.class);
when(result.getService()).thenReturn(TracTracAdapterFactory.INSTANCE);
return result;
}
@Override
protected ServiceTracker<SwissTimingAdapterFactory, SwissTimingAdapterFactory> createAndOpenSwissTimingAdapterTracker(
BundleContext context) {
@SuppressWarnings("unchecked")
ServiceTracker<SwissTimingAdapterFactory, SwissTimingAdapterFactory> result = mock(ServiceTracker.class);
when(result.getService()).thenReturn(new SwissTimingAdapterFactory() {
swissTimingAdapterFactory = new SwissTimingAdapterFactory() {
@Override
public SwissTimingAdapter getOrCreateSwissTimingAdapter(DomainFactory baseDomainFactory) {
return new SwissTimingAdapter() {
@Override
public List<com.sap.sailing.domain.swisstimingadapter.RaceRecord> getSwissTimingRaceRecords(
String hostname, int port) throws InterruptedException,
UnknownHostException, IOException, ParseException {
String hostname, int port) throws InterruptedException, UnknownHostException, IOException,
ParseException {
// TODO Auto-generated method stub
return null;
}
@@ -148,45 +106,43 @@ public class SailingServiceImplMock extends SailingServiceImpl {
}
};
}
});
return result;
};
}
public ScoreCorrectionProvider getScoreCorrectionProvider() {
return scoreCorrectionProvider;
}
@Override
protected ServiceTracker<SwissTimingReplayServiceFactory, SwissTimingReplayServiceFactory> createAndOpenSwissTimingReplayServiceTracker(
BundleContext context) {
@SuppressWarnings("unchecked")
ServiceTracker<SwissTimingReplayServiceFactory, SwissTimingReplayServiceFactory> result = mock(ServiceTracker.class);
final SwissTimingReplayServiceFactory swissTimingReplayService = new SwissTimingReplayServiceFactory() {
@Override
public SwissTimingReplayService createSwissTimingReplayService(
com.sap.sailing.domain.swisstimingadapter.DomainFactory domainFactory) {
// TODO Auto-generated method stub
return null;
}
};
when(result.getService()).thenReturn(swissTimingReplayService);
return result;
protected TracTracAdapterFactory getTracTracAdapterFactory() {
return tracTracAdapterFactory;
}
@Override
protected SwissTimingAdapterFactory getSwissTimingAdapterFactory() {
return swissTimingAdapterFactory;
}
@Override
protected SwissTimingReplayService getSwissTimingReplayService() {
return swissTimingReplayService;
}
@Override
protected RaceLogTrackingAdapterFactory getRaceLogTrackingAdapterFactory() {
return raceLogTrackingAdapterFactory;
}
@Override
protected ServiceTracker<RaceLogTrackingAdapterFactory, RaceLogTrackingAdapterFactory> createAndOpenRaceLogTrackingAdapterTracker(
BundleContext context) {
@SuppressWarnings("unchecked")
ServiceTracker<RaceLogTrackingAdapterFactory, RaceLogTrackingAdapterFactory> result = mock(ServiceTracker.class);
RaceLogTrackingAdapterFactory factory = RaceLogTrackingAdapterFactory.INSTANCE;
when(result.getService()).thenReturn(factory);
return result;
protected ReplicationService getReplicationService() {
return replicationService;
}
@Override
protected RacingEventService getService() {
if (service == null) {
service = new RacingEventServiceImpl();
}
return service;
}
public RacingEventService getRacingEventService() {
return getService();
}
@@ -9,7 +9,7 @@
<!-- event navigation-->
<div class="{local_res.css.eventnavigation} {local_res.css.eventnavigationcompact}">
<div class="{res.mainCss.grid}">
<div class="{res.mainCss.grid}" style="margin-left:5rem;margin-right:5rem;">
<div class="{res.mediaCss.columns}">
<g:Anchor ui:field="regattaLink">
<img ui:field="eventLogo" alt="" height="41" width="41" class="{local_res.css.eventnavigationcompact_logo}"></img>
@@ -7,7 +7,7 @@
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.regattaanalytics.RegattaAnalyticsResources" />
<g:HTMLPanel>
<div class="{res.mainCss.grid}">
<div class="{res.mainCss.grid}" style="margin-left:5rem;margin-right:5rem;">
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<h3><ui:text from="{i18n.competitorsAnalytics}" /></h3>
</div>
@@ -7,7 +7,7 @@
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboardResources" />
<g:HTMLPanel>
<div class="{res.mainCss.grid}">
<div class="{res.mainCss.grid}" style="margin-left:5rem;margin-right:5rem;margin-bottom:1rem;">
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<p ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></p>
<p ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
@@ -7,7 +7,7 @@
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboardResources" />
<g:HTMLPanel>
<div class="{res.mainCss.grid}">
<div class="{res.mainCss.grid}" style="margin-left:5rem;margin-right:5rem;margin-bottom:1rem;">
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
<p ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></p>
<p ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
@@ -38,6 +38,8 @@
text-align: center;
}
.regattaleaderboard {
margin-left: 5rem;
margin-right: 5rem;
font-size: 15px;
font-size: 1rem;
width: 100%;
@@ -18,11 +18,11 @@ import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
import com.sap.sailing.domain.common.racelog.tracking.MappableToDevice;
import com.sap.sailing.gwt.ui.adminconsole.DeviceMappingQRCodeWidget.QRCodeURLCreationException;
import com.sap.sailing.domain.common.racelog.tracking.QRCodeURLCreationException;
import com.sap.sailing.gwt.ui.adminconsole.ItemToMapToDeviceSelectionPanel.SelectionChangedHandler;
import com.sap.sailing.gwt.ui.client.GwtUrlHelper;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.BetterDateTimeBox;
@@ -103,7 +103,7 @@ public class AddDeviceMappingToRaceLogDialog extends DataEntryDialog<DeviceMappi
});
deviceId = createTextBox("");
itemSelectionPanel = new ItemToMapToDeviceSelectionPanel(sailingService, stringMessages, errorReporter,
new SelectionChangedHandler() {
@Override
@@ -120,7 +120,7 @@ public class AddDeviceMappingToRaceLogDialog extends DataEntryDialog<DeviceMappi
}
}, mapping != null ? mapping.mappedTo : null);
//load table content
// load table content
sailingService.getCompetitorRegistrations(leaderboardName, raceColumnName, fleetName,
itemSelectionPanel.getSetCompetitorsCallback());
@@ -136,7 +136,7 @@ public class AddDeviceMappingToRaceLogDialog extends DataEntryDialog<DeviceMappi
qrWidget = new DeviceMappingQRCodeWidget(stringMessages, new DeviceMappingQRCodeWidget.URLFactory() {
@SuppressWarnings("deprecation")
@Override
public String createURL(String baseUrlWithoutTrailingSlash, String mappedItemQueryParam)
public String createURL(String baseUrlWithoutTrailingSlash, String mappedItemType, String mappedItemId)
throws QRCodeURLCreationException {
if (from.getValue() == null) {
throw new QRCodeURLCreationException("from not set");
@@ -147,14 +147,11 @@ public class AddDeviceMappingToRaceLogDialog extends DataEntryDialog<DeviceMappi
long fromMillis = from.getValue().getTime();
long toMillis = to.getValue().getTime();
if (fromMillis > toMillis) {
throw new QRCodeURLCreationException("from cannt lie after to");
throw new QRCodeURLCreationException("from can't lie after to");
}
return baseUrlWithoutTrailingSlash + DeviceMappingConstants.APK_PATH + "?"
+ RaceLogServletConstants.PARAMS_LEADERBOARD_NAME + "=" + DeviceMappingQRCodeWidget.encode(leaderboardName) + "&"
+ RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME + "=" + DeviceMappingQRCodeWidget.encode(raceColumnName)
+ "&" + RaceLogServletConstants.PARAMS_RACE_FLEET_NAME + "=" + DeviceMappingQRCodeWidget.encode(fleetName)
+ "&" + mappedItemQueryParam + "&" + DeviceMappingConstants.URL_FROM_MILLIS + "=" + fromMillis
+ "&" + DeviceMappingConstants.URL_TO_MILLIS + "=" + toMillis;
return DeviceMappingConstants.getDeviceMappingForRaceLogUrl(baseUrlWithoutTrailingSlash,
leaderboardName, raceColumnName, fleetName, mappedItemType, mappedItemId, fromMillis, toMillis,
GwtUrlHelper.INSTANCE);
}
});
qrWidget.generateQRCode();
@@ -13,15 +13,16 @@ import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
import com.sap.sailing.gwt.ui.adminconsole.DeviceMappingQRCodeWidget.QRCodeURLCreationException;
import com.sap.sailing.domain.common.racelog.tracking.QRCodeURLCreationException;
import com.sap.sailing.gwt.ui.adminconsole.ItemToMapToDeviceSelectionPanel.SelectionChangedHandler;
import com.sap.sailing.gwt.ui.client.GwtUrlHelper;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.common.client.GenericListBox;
import com.sap.sailing.gwt.ui.common.client.GenericListBox.ValueBuilder;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.MarkDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.controls.GenericListBox;
import com.sap.sse.gwt.client.controls.GenericListBox.ValueBuilder;
public class AddDeviceMappingToRegattaLogDialog extends AbstractCancelableDialog {
private DeviceMappingQRCodeWidget qrWidget;
@@ -35,11 +36,11 @@ public class AddDeviceMappingToRegattaLogDialog extends AbstractCancelableDialog
setupUi();
center();
}
@Override
protected void addMainContent(Panel mainPanel) {
super.addMainContent(mainPanel);
CaptionPanel inputPanel = new CaptionPanel();
Grid inputGrid = new Grid(1, 2);
inputPanel.add(inputGrid);
@@ -62,13 +63,13 @@ public class AddDeviceMappingToRegattaLogDialog extends AbstractCancelableDialog
public void onSuccess(Collection<EventDTO> result) {
events.addItems(result);
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not load events: " + caught.getMessage());
}
});
itemSelectionPanel = new ItemToMapToDeviceSelectionPanel(sailingService, stringMessages, errorReporter,
new SelectionChangedHandler() {
@Override
@@ -85,33 +86,31 @@ public class AddDeviceMappingToRegattaLogDialog extends AbstractCancelableDialog
}
}, null);
//load table content
// load table content
sailingService.getCompetitorRegistrations(leaderboardName, itemSelectionPanel.getSetCompetitorsCallback());
//TODO marks from RegattaLog also?
// TODO marks from RegattaLog also?
qrWidget = new DeviceMappingQRCodeWidget(stringMessages, new DeviceMappingQRCodeWidget.URLFactory() {
@Override
public String createURL(String baseUrlWithoutTrailingSlash, String mappedItemQueryParam)
public String createURL(String baseUrlWithoutTrailingSlash, String mappedItemType, String mappedItemId)
throws QRCodeURLCreationException {
if (events.getValue() == null) {
throw new QRCodeURLCreationException("no event selected");
}
String eventIdAsString = events.getValue().id.toString();
return baseUrlWithoutTrailingSlash + DeviceMappingConstants.URL_BASE
+ "?" + DeviceMappingConstants.URL_EVENT_ID + "=" + DeviceMappingQRCodeWidget.encode(eventIdAsString)
+ "&" + DeviceMappingConstants.URL_LEADERBOARD_NAME + "=" + DeviceMappingQRCodeWidget.encode(leaderboardName)
+ "&" + mappedItemQueryParam;
return DeviceMappingConstants.getDeviceMappingForRegattaLogUrl(baseUrlWithoutTrailingSlash, eventIdAsString,
leaderboardName, mappedItemType, mappedItemId, GwtUrlHelper.INSTANCE);
}
});
qrWidget.generateQRCode();
VerticalPanel leftSidePanel = new VerticalPanel();
leftSidePanel.add(inputPanel);
CaptionPanel qrContentPanel = new CaptionPanel();
leftSidePanel.add(qrContentPanel);
qrContentPanel.add(qrWidget);
HorizontalPanel panel = new HorizontalPanel();
mainPanel.add(panel);
panel.add(leftSidePanel);
@@ -4,7 +4,6 @@ import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
@@ -13,7 +12,7 @@ import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.adminconsole.DeviceMappingQRCodeWidget.QRCodeURLCreationException;
import com.sap.sailing.domain.common.racelog.tracking.QRCodeURLCreationException;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.QRCodeComposite;
@@ -91,9 +90,4 @@ public abstract class BaseQRIdentifierWidget implements IsWidget {
protected void setError(String text) {
error.setText(text);
}
public static String encode(String value) {
//pathSegment instead of queryString, so that ' ' is encoded as '%20'
return URL.encodePathSegment(value);
}
}
@@ -38,6 +38,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
private final TextBox displayColorTextBox;
private final ListBox threeLetterIocCountryCode;
private final TextBox sailId;
private final TextBox email;
private final StringMessages stringMessages;
public CompetitorEditDialog(final StringMessages stringMessages, CompetitorDTO competitorToEdit,
@@ -89,6 +90,8 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
}
this.name = createTextBox(competitorToEdit.getName());
this.email = createTextBox(competitorToEdit.getEmail());
this.email.getElement().setPropertyString("placeholder", stringMessages.pleaseEnterAnEmail());
this.displayColorTextBox = createTextBox(competitorToEdit.getColor() == null ? "" : competitorToEdit.getColor().getAsHtml());
this.threeLetterIocCountryCode = createListBox(/* isMultipleSelect */ false);
CountryCodeFactory ccf = CountryCodeFactory.INSTANCE;
@@ -170,7 +173,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
}
}
BoatClassDTO boatClass = new BoatClassDTO(boatClassName.getValue(boatClassName.getSelectedIndex()), 0);
CompetitorDTO result = new CompetitorDTOImpl(name.getText(), color,
CompetitorDTO result = new CompetitorDTOImpl(name.getText(), color, email.getText(),
/* twoLetterIsoCountryCode */ null,
threeLetterIocCountryCode.getValue(threeLetterIocCountryCode.getSelectedIndex()),
/* countryName */ null, sailId.getText(), competitorToEdit.getIdAsString(),
@@ -180,7 +183,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
@Override
protected Widget getAdditionalWidget() {
Grid result = new Grid(5, 2);
Grid result = new Grid(6, 2);
result.setWidget(0, 0, new Label(stringMessages.name()));
result.setWidget(0, 1, name);
result.setWidget(1, 0, new Label(stringMessages.sailNumber()));
@@ -189,8 +192,10 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
result.setWidget(2, 1, threeLetterIocCountryCode);
result.setWidget(3, 0, new Label(stringMessages.color()));
result.setWidget(3, 1, displayColorTextBox);
result.setWidget(4, 0, new Label(stringMessages.boatClass()));
result.setWidget(4, 1, boatClassName);
result.setWidget(4, 0, new Label(stringMessages.email()));
result.setWidget(4, 1, email);
result.setWidget(5, 0, new Label(stringMessages.boatClass()));
result.setWidget(5, 1, boatClassName);
return result;
}
@@ -1,18 +1,24 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
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;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
@@ -20,8 +26,13 @@ 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.controls.GenericListBox;
import com.sap.sse.gwt.client.controls.GenericListBox.ValueBuilder;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
/**
@@ -43,8 +54,8 @@ public class CompetitorPanel extends SimplePanel {
this(sailingService, null, stringMessages, errorReporter);
}
public CompetitorPanel(final SailingServiceAsync sailingService, String leaderboardName, final StringMessages stringMessages,
final ErrorReporter errorReporter) {
public CompetitorPanel(final SailingServiceAsync sailingService, final String leaderboardName,
final StringMessages stringMessages, final ErrorReporter errorReporter) {
super();
this.sailingService = sailingService;
this.stringMessages = stringMessages;
@@ -79,16 +90,56 @@ public class CompetitorPanel extends SimplePanel {
buttonPanel.add(allowReloadButton);
Button addCompetitorButton = new Button(stringMessages.add());
addCompetitorButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
openAddCompetitorDialog();
}
});
@Override
public void onClick(ClickEvent event) {
openAddCompetitorDialog();
}
});
buttonPanel.add(addCompetitorButton);
Button selectAllButton = new Button(stringMessages.selectAll());
selectAllButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
for (CompetitorDTO c : competitorTable.getDataProvider().getList()) {
competitorSelectionModel.setSelected(c, true);
}
}
});
buttonPanel.add(selectAllButton);
//only if this competitor panel is connected to a leaderboard, we want to enable invitations
if (leaderboardName != null) {
final Button inviteCompetitorsButton = new Button(stringMessages.inviteCompetitors());
inviteCompetitorsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
Set<CompetitorDTO> competitors = competitorSelectionModel.getSelectedSet();
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;
}
});
buttonPanel.add(inviteCompetitorsButton);
}
competitorsPanel.add(buttonPanel);
//competitor table
// competitor table
ImagesBarColumn<CompetitorDTO, CompetitorConfigImagesBarCell> competitorActionColumn = new ImagesBarColumn<CompetitorDTO, CompetitorConfigImagesBarCell>(
new CompetitorConfigImagesBarCell(stringMessages));
competitorActionColumn.setFieldUpdater(new FieldUpdater<CompetitorDTO, String>() {
@@ -112,21 +163,24 @@ public class CompetitorPanel extends SimplePanel {
}
});
allowReloadButton.setEnabled(!competitorSelectionModel.getSelectedSet().isEmpty());
if(leaderboardName != null) {
if (leaderboardName != null) {
refreshCompetitorList();
}
}
private void allowUpdate(final Iterable<CompetitorDTO> competitors) {
List<CompetitorDTO> serializableSingletonList = new ArrayList<CompetitorDTO>();
Util.addAll(competitors, serializableSingletonList);
sailingService.allowCompetitorResetToDefaults(serializableSingletonList, new AsyncCallback<Void>() {
@Override public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to allow resetting competitors "+competitors
+" to defaults: "+caught.getMessage());
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to allow resetting competitors " + competitors
+ " to defaults: " + caught.getMessage());
}
@Override public void onSuccess(Void result) {
@Override
public void onSuccess(Void result) {
Window.alert(stringMessages.successfullyAllowedCompetitorReset(competitors.toString()));
}
});
@@ -143,7 +197,7 @@ public class CompetitorPanel extends SimplePanel {
sailingService.addOrUpdateCompetitor(competitor, new AsyncCallback<CompetitorDTO>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to update competitor: "+caught.getMessage());
errorReporter.reportError("Error trying to update competitor: " + caught.getMessage());
}
@Override
@@ -159,6 +213,101 @@ public class CompetitorPanel extends SimplePanel {
}).show();
}
private class SelectEventAndHostnameDialog extends DataEntryDialog<Pair<EventDTO, String>> {
private GenericListBox<EventDTO> events;
private TextBox serverUrl;
public SelectEventAndHostnameDialog(DialogCallback<Pair<EventDTO, String>> callback) {
super(stringMessages.selectEventForInvitation(), null, stringMessages.inviteCompetitors(), stringMessages.cancel(),
new Validator<Pair<EventDTO, String>>() {
@Override
public String getErrorMessage(Pair<EventDTO, String> valueToValidate) {
if (valueToValidate.getA() == null) {
return stringMessages.pleaseSelectAnEvent();
} else if (valueToValidate.getB() == null || valueToValidate.getB().isEmpty()) {
return stringMessages.pleaseEnterA(stringMessages.hostname());
}
return null;
}
}, false, callback);
}
@Override
protected Pair<EventDTO, String> getResult() {
EventDTO event = events.getValue();
String serverUrlString = serverUrl.getValue();
if (serverUrlString.endsWith("/")) {
serverUrlString = serverUrlString.substring(0, serverUrlString.length() - 1);
}
return new Pair<>(event, serverUrlString);
}
@Override
protected Widget getAdditionalWidget() {
Grid grid = new Grid(2, 2);
grid.setWidget(0, 0, createLabel(stringMessages.hostname()));
serverUrl = createTextBox(Window.Location.getProtocol() + "//" + Window.Location.getHost());
grid.setWidget(0, 1, serverUrl);
grid.setWidget(1, 0, createLabel(stringMessages.event()));
events = createGenericListBox(new ValueBuilder<EventDTO>() {
@Override
public String getValue(EventDTO item) {
if (item == null) {
return "";
}
return item.getName();
}
}, false);
grid.setWidget(1, 1, events);
events.addItem((EventDTO) null);
sailingService.getEventsForLeaderboard(leaderboardName, new AsyncCallback<Collection<EventDTO>>() {
@Override
public void onSuccess(Collection<EventDTO> result) {
events.addItems(result);
}
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Could not load events: " + caught.getMessage());
}
});
return grid;
}
}
private String getLocaleInfo() {
return LocaleInfo.getCurrentLocale().getLocaleName();
}
private void openChooseEventDialogAndSendMails(final Set<CompetitorDTO> competitors) {
new SelectEventAndHostnameDialog(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.sendingMailsSuccessfull());
}
});
}
@Override
public void cancel() {
}
}).show();
}
public void refreshCompetitorList() {
competitorTable.refreshCompetitorList(leaderboardName);
}
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.ui.adminconsole;
import com.google.gwt.http.client.URL;
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
import com.sap.sailing.domain.common.racelog.tracking.QRCodeURLCreationException;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.QRCodeComposite;
@@ -13,15 +14,8 @@ public class DeviceMappingQRCodeWidget extends BaseQRIdentifierWidget {
private String mappedItemId;
private String mappedItemType;
static class QRCodeURLCreationException extends Exception {
private static final long serialVersionUID = -8243995470804772458L;
public QRCodeURLCreationException(String message) {
super(message);
}
}
static interface URLFactory {
String createURL(String baseUrlWithoutTrailingSlash, String mappedItemQueryParam)
String createURL(String baseUrlWithoutTrailingSlash, String mappedItemType, String mappedItemId)
throws QRCodeURLCreationException;
}
@@ -52,6 +46,6 @@ public class DeviceMappingQRCodeWidget extends BaseQRIdentifierWidget {
throw new QRCodeURLCreationException("No item selected for mapping");
}
return urlFactory.createURL(serverUrl, mappedItemType + "=" + encode(mappedItemId));
return urlFactory.createURL(serverUrl, mappedItemType, mappedItemId);
}
}
@@ -0,0 +1,22 @@
package com.sap.sailing.gwt.ui.client;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.http.client.URL;
import com.sap.sse.common.util.UrlHelper;
/**
* Tycho complains that {@link com.google.gwt} cannot be resolved when placing this in *common projects, where it would ideally
* go (then we could also auto-determine if GWT context is present, e.g. through {@link GWT#isClient}).
*
* @author Fredrik Teschke
*
*/
public enum GwtUrlHelper implements UrlHelper {
INSTANCE;
@Override
public String encodeUrl(String decodedUrlString) {
return URL.encode(decodedUrlString);
}
}
@@ -87,6 +87,7 @@ import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
import com.sap.sse.common.Util;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.mail.MailException;
import com.sap.sse.common.search.KeywordQuery;
import com.sap.sse.gwt.client.filestorage.FileStorageManagementGwtService;
@@ -573,4 +574,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
List<DeviceMappingDTO> getDeviceMappingsFromLogHierarchy(String leaderboardName, String raceColumnName,
String fleetName) throws TransformationException;
void inviteCompetitorsForTrackingViaEmail(String serverUrlWithoutTrailingSlash, EventDTO event,
String leaderboardName, Set<CompetitorDTO> competitors, String localeInfo) throws MailException;
}
@@ -684,4 +684,8 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
void createRegattaStructure(Iterable<RegattaDTO> regattaNames,
EventDTO newEvent, AsyncCallback<Void> asyncCallback);
void getActiveFileStorageServiceName(AsyncCallback<String> callback);
void inviteCompetitorsForTrackingViaEmail(String serverUrlWithoutTrailingSlash, EventDTO event,
String leaderboardName, Set<CompetitorDTO> competitors, String localeInfo, AsyncCallback<Void> callback);
}
@@ -1142,4 +1142,11 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
String scoringSchemeHighPointEssOverallDescription();
String timeBetweenRaceStartAndCompetitorStartInSeconds();
String timeBetweenRaceStartAndCompetitorStartInSecondsTooltip();
String email();
String pleaseEnterAnEmail();
String inviteCompetitors();
String notAllCompetitorsProvideEmail();
String sendingMailsFailed();
String sendingMailsSuccessfull();
String selectEventForInvitation();
}
@@ -1122,4 +1122,11 @@ fileStorage=File Storage
active=Active
scoringSchemeHighPointEssOverallDescription=Score in points. Winner of an act scores 10 points, 2nd - 9 points, .... Any tie in the overall Extreme Sailing Series is broken in favour of the competitor with the most Act wins. If that does not break the tie, the result in the last Act will be used.
timeBetweenRaceStartAndCompetitorStartInSeconds=Start delay
timeBetweenRaceStartAndCompetitorStartInSecondsTooltip=Time between the start of the race and the time the competitor passed the start waypoint. Negative time suggests OCS.
timeBetweenRaceStartAndCompetitorStartInSecondsTooltip=Time between the start of the race and the time the competitor passed the start waypoint. Negative time suggests OCS.
email=E-Mail
pleaseEnterAnEmail=Please enter an E-Mail.
inviteCompetitors=Invite competitors
notAllCompetitorsProvideEmail=Not all competitors provide an E-Mail
sendingMailsFailed=Sending Mails failed
sendingMailsSuccessfull=Successfully sent E-Mails
selectEventForInvitation=Select Event for Invitation
@@ -1112,4 +1112,11 @@ fileStorage=Datei Speicherung
active=Aktiv
scoringSchemeHighPointEssOverallDescription=High Point System, der Gewinner eines Acts erhält 10 Punkte, der Zweite 9 und so weiter.
timeBetweenRaceStartAndCompetitorStartInSeconds=Startverzug
timeBetweenRaceStartAndCompetitorStartInSecondsTooltip=Zeit seit dem Start der Wettfahrt, nach der der Teilnehmer die Startmarke passiert hat. Negative Werte suggerieren einen Frühstart.
timeBetweenRaceStartAndCompetitorStartInSecondsTooltip=Zeit seit dem Start der Wettfahrt, nach der der Teilnehmer die Startmarke passiert hat. Negative Werte suggerieren einen Frühstart.
email=E-Mail
pleaseEnterAnEmail=Bitte geben Sie eine E-Mail ein.
inviteCompetitors=Teilnehmer einladen
notAllCompetitorsProvideEmail=Nicht alle Teilnehmer haben eine E-Mail angegeben
sendingMailsFailed=Versenden der E-Mails fehlgeschlagen
sendingMailsSuccessfull=Versenden der E-Mails war erfolgreich!
selectEventForInvitation=Event für Einladung auswählen
@@ -1061,4 +1061,11 @@ fileStorage=File Storage
active=Active
scoringSchemeHighPointEssOverallDescription=Score in points. Winner of an act scores 10 points, 2nd - 9 points, .... Any tie in the overall Extreme Sailing Series is broken in favour of the competitor with the most Act wins. If that does not break the tie, the result in the last Act will be used.
timeBetweenRaceStartAndCompetitorStartInSeconds=Start delay
timeBetweenRaceStartAndCompetitorStartInSecondsTooltip=Time between the start of the race and the time the competitor passed the start waypoint. Negative time suggests OCS.
timeBetweenRaceStartAndCompetitorStartInSecondsTooltip=Time between the start of the race and the time the competitor passed the start waypoint. Negative time suggests OCS.
email=эмаль
pleaseEnterAnEmail=Пожалуйста, введите эмаль
inviteCompetitors=приглашать Участники
notAllCompetitorsProvideEmail=Not all competitors provide an E-Mail
sendingMailsFailed=Sending Mails failed
sendingMailsSuccessfull=Successfully sent E-Mails
selectEventForInvitation=Select Event for Invitation
@@ -418,6 +418,7 @@ import com.sap.sse.common.Util.Triple;
import com.sap.sse.common.impl.MillisecondsDurationImpl;
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.search.KeywordQuery;
import com.sap.sse.common.search.Result;
import com.sap.sse.filestorage.FileStorageService;
@@ -431,8 +432,10 @@ import com.sap.sse.replication.ReplicationFactory;
import com.sap.sse.replication.ReplicationMasterDescriptor;
import com.sap.sse.replication.ReplicationService;
import com.sap.sse.replication.impl.ReplicaDescriptor;
import com.sap.sse.util.ServiceTrackerFactory;
import com.sapsailing.xrr.structureimport.eventimport.RegattaJSON;
/**
* The server side implementation of the RPC service.
*/
@@ -496,6 +499,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
private final SwissTimingReplayService swissTimingReplayService;
private final QuickRanksLiveCache quickRanksLiveCache;
public SailingServiceImpl() {
BundleContext context = Activator.getDefault();
Activator activator = Activator.getInstance();
@@ -503,21 +507,25 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
activator.setSailingService(this); // register so this service is informed when the bundle shuts down
}
quickRanksLiveCache = new QuickRanksLiveCache(this);
racingEventServiceTracker = createAndOpenRacingEventServiceTracker(context);
replicationServiceTracker = createAndOpenReplicationServiceTracker(context);
resultUrlRegistryServiceTracker = createAndOpenResultUrlRegistryServiceTracker(context);
swissTimingAdapterTracker = createAndOpenSwissTimingAdapterTracker(context);
tractracAdapterTracker = createAndOpenTracTracAdapterTracker(context);
raceLogTrackingAdapterTracker = createAndOpenRaceLogTrackingAdapterTracker(context);
deviceIdentifierStringSerializationHandlerTracker = createAndOpenDeviceIdentifierStringSerializationHandlerTracker(context);
igtimiAdapterTracker = createAndOpenIgtimiTracker(context);
racingEventServiceTracker = ServiceTrackerFactory.createAndOpen(context, RacingEventService.class);
replicationServiceTracker = ServiceTrackerFactory.createAndOpen(context, ReplicationService.class);
resultUrlRegistryServiceTracker = ServiceTrackerFactory.createAndOpen(context, ResultUrlRegistry.class);
swissTimingAdapterTracker = ServiceTrackerFactory.createAndOpen(context, SwissTimingAdapterFactory.class);
tractracAdapterTracker = ServiceTrackerFactory.createAndOpen(context, TracTracAdapterFactory.class);
raceLogTrackingAdapterTracker = ServiceTrackerFactory.createAndOpen(context,
RaceLogTrackingAdapterFactory.class);
deviceIdentifierStringSerializationHandlerTracker = ServiceTrackerFactory.createAndOpen(context,
DeviceIdentifierStringSerializationHandler.class);
igtimiAdapterTracker = ServiceTrackerFactory.createAndOpen(context, IgtimiConnectionFactory.class);
baseDomainFactory = getService().getBaseDomainFactory();
mongoObjectFactory = getService().getMongoObjectFactory();
domainObjectFactory = getService().getDomainObjectFactory();
// TODO what about passing on the mongo/domain object factory to obtain an according SwissTimingAdapterPersistence instance similar to how the tractracDomainObjectFactory etc. are created below?
swissTimingAdapterPersistence = SwissTimingAdapterPersistence.INSTANCE;
swissTimingReplayService = getSwissTimingReplayService(context);
scoreCorrectionProviderServiceTracker = createAndOpenScoreCorrectionProviderServiceTracker(context);
swissTimingReplayService = ServiceTrackerFactory.createAndOpen(context, SwissTimingReplayServiceFactory.class)
.getService().createSwissTimingReplayService(getSwissTimingAdapter().getSwissTimingDomainFactory());
scoreCorrectionProviderServiceTracker = ServiceTrackerFactory.createAndOpen(context,
ScoreCorrectionProvider.class);
tractracDomainObjectFactory = com.sap.sailing.domain.tractracadapter.persistence.PersistenceFactory.INSTANCE
.createDomainObjectFactory(mongoObjectFactory.getDatabase(), getTracTracAdapter()
.getTracTracDomainFactory());
@@ -556,89 +564,26 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
quickRanksLiveCache.stop();
}
protected SwissTimingReplayService getSwissTimingReplayService(BundleContext context) {
return createAndOpenSwissTimingReplayServiceTracker(context).getService().createSwissTimingReplayService(getSwissTimingAdapter().getSwissTimingDomainFactory());
protected SwissTimingAdapterFactory getSwissTimingAdapterFactory() {
return swissTimingAdapterTracker.getService();
}
protected SwissTimingAdapter getSwissTimingAdapter() {
return swissTimingAdapterTracker.getService().getOrCreateSwissTimingAdapter(baseDomainFactory);
return getSwissTimingAdapterFactory().getOrCreateSwissTimingAdapter(baseDomainFactory);
}
protected TracTracAdapterFactory getTracTracAdapterFactory() {
return tractracAdapterTracker.getService();
}
protected TracTracAdapter getTracTracAdapter() {
return tractracAdapterTracker.getService().getOrCreateTracTracAdapter(baseDomainFactory);
}
protected ServiceTracker<TracTracAdapterFactory, TracTracAdapterFactory> createAndOpenTracTracAdapterTracker(BundleContext context) {
ServiceTracker<TracTracAdapterFactory, TracTracAdapterFactory> result = new ServiceTracker<TracTracAdapterFactory, TracTracAdapterFactory>(
context, TracTracAdapterFactory.class.getName(), null);
result.open();
return result;
}
protected ServiceTracker<IgtimiConnectionFactory, IgtimiConnectionFactory> createAndOpenIgtimiTracker(BundleContext context) {
ServiceTracker<IgtimiConnectionFactory, IgtimiConnectionFactory> result = new ServiceTracker<IgtimiConnectionFactory, IgtimiConnectionFactory>(
context, IgtimiConnectionFactory.class.getName(), null);
result.open();
return result;
}
protected ServiceTracker<SwissTimingAdapterFactory, SwissTimingAdapterFactory> createAndOpenSwissTimingAdapterTracker(
BundleContext context) {
ServiceTracker<SwissTimingAdapterFactory, SwissTimingAdapterFactory> result = new ServiceTracker<SwissTimingAdapterFactory, SwissTimingAdapterFactory>(
context, SwissTimingAdapterFactory.class.getName(), null);
result.open();
return result;
}
protected ServiceTracker<SwissTimingReplayServiceFactory, SwissTimingReplayServiceFactory> createAndOpenSwissTimingReplayServiceTracker(
BundleContext context) {
ServiceTracker<SwissTimingReplayServiceFactory, SwissTimingReplayServiceFactory> result = new ServiceTracker<SwissTimingReplayServiceFactory, SwissTimingReplayServiceFactory>(
context, SwissTimingReplayServiceFactory.class.getName(), null);
result.open();
return result;
}
protected ServiceTracker<RaceLogTrackingAdapterFactory, RaceLogTrackingAdapterFactory> createAndOpenRaceLogTrackingAdapterTracker(
BundleContext context) {
ServiceTracker<RaceLogTrackingAdapterFactory, RaceLogTrackingAdapterFactory> result =
new ServiceTracker<RaceLogTrackingAdapterFactory, RaceLogTrackingAdapterFactory>(
context, RaceLogTrackingAdapterFactory.class.getName(), null);
result.open();
return result;
return getTracTracAdapterFactory().getOrCreateTracTracAdapter(baseDomainFactory);
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
}
protected ServiceTracker<RacingEventService, RacingEventService> createAndOpenRacingEventServiceTracker(
BundleContext context) {
ServiceTracker<RacingEventService, RacingEventService> result = new ServiceTracker<RacingEventService, RacingEventService>(
context, RacingEventService.class.getName(), null);
result.open();
return result;
}
protected ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> createAndOpenResultUrlRegistryServiceTracker(
BundleContext context) {
ServiceTracker<ResultUrlRegistry, ResultUrlRegistry> result = new ServiceTracker<ResultUrlRegistry, ResultUrlRegistry>(
context, ResultUrlRegistry.class.getName(), null);
result.open();
return result;
}
/**
* Asks the OSGi system for registered score correction provider services
*/
protected ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> createAndOpenScoreCorrectionProviderServiceTracker(
BundleContext bundleContext) {
ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> tracker = new ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider>(bundleContext,
ScoreCorrectionProvider.class.getName(),
/* customizer */null);
tracker.open();
return tracker;
}
@Override
public Iterable<String> getScoreCorrectionProviderNames() {
List<String> result = new ArrayList<String>();
@@ -685,15 +630,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return new ScoreCorrectionProviderDTO(scoreCorrectionProvider.getName(), hasResultsForBoatClassFromDateByEventName);
}
protected ServiceTracker<ReplicationService, ReplicationService> createAndOpenReplicationServiceTracker(
BundleContext context) {
ServiceTracker<ReplicationService, ReplicationService> result =
new ServiceTracker<ReplicationService, ReplicationService>(
context, ReplicationService.class.getName(), null);
result.open();
return result;
}
/**
* If <code>date</code> is <code>null</code>, the {@link LiveLeaderboardUpdater} for the
* <code>leaderboardName</code> requested is obtained or created if it doesn't exist yet. The request is then passed
@@ -1116,10 +1052,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
}
private SwissTimingReplayService getSwissTimingReplayService() {
return swissTimingReplayService;
}
@Override
public List<TracTracConfigurationDTO> getPreviousTracTracConfigurations() throws Exception {
Iterable<TracTracConfiguration> configs = tractracDomainObjectFactory.getTracTracConfigurations();
@@ -2239,7 +2171,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return racingEventServiceTracker.getService(); // grab the service
}
private ReplicationService getReplicationService() {
protected ReplicationService getReplicationService() {
return replicationServiceTracker.getService();
}
@@ -2699,6 +2631,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
}
}
protected SwissTimingReplayService getSwissTimingReplayService() {
return swissTimingReplayService;
}
@Override
public List<SwissTimingReplayRaceDTO> listSwissTiminigReplayRaces(String swissTimingUrl) {
@@ -4538,12 +4474,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
DynamicBoat boat = new BoatImpl(competitor.getName() + " boat", boatClass, competitor.getSailID());
result = getBaseDomainFactory().convertToCompetitorDTO(
getBaseDomainFactory().getOrCreateCompetitor(UUID.randomUUID(), competitor.getName(),
competitor.getColor(), team, boat));
competitor.getColor(), competitor.getEmail(), team, boat));
} else {
result = getBaseDomainFactory().convertToCompetitorDTO(
getService().apply(
new UpdateCompetitor(competitor.getIdAsString(), competitor.getName(), competitor
.getColor(), competitor.getSailID(), nationality, existingCompetitor.getTeam().getImage())));
.getColor(), competitor.getEmail(), competitor.getSailID(), nationality, existingCompetitor.getTeam().getImage())));
}
return result;
}
@@ -4736,9 +4672,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
private IgtimiConnectionFactory getIgtimiConnectionFactory() {
return igtimiAdapterTracker.getService();
}
protected RaceLogTrackingAdapterFactory getRaceLogTrackingAdapterFactory() {
return raceLogTrackingAdapterTracker.getService();
}
protected RaceLogTrackingAdapter getRaceLogTrackingAdapter() {
return raceLogTrackingAdapterTracker.getService().getAdapter(getBaseDomainFactory());
return getRaceLogTrackingAdapterFactory().getAdapter(getBaseDomainFactory());
}
@Override
@@ -5180,16 +5120,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
raceLog.add(event);
}
private ServiceTracker<DeviceIdentifierStringSerializationHandler, DeviceIdentifierStringSerializationHandler>
createAndOpenDeviceIdentifierStringSerializationHandlerTracker(BundleContext context) {
ServiceTracker<DeviceIdentifierStringSerializationHandler, DeviceIdentifierStringSerializationHandler> tracker =
new ServiceTracker<DeviceIdentifierStringSerializationHandler, DeviceIdentifierStringSerializationHandler>(
context, DeviceIdentifierStringSerializationHandler.class, null);
tracker.open();
return tracker;
}
@Override
public List<String> getDeserializableDeviceIdentifierTypes() {
List<String> result = new ArrayList<String>();
@@ -5436,13 +5366,16 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
return getService().getFileStorageManagementService().getFileStorageService(name);
}
private Locale getLocale(String localeInfoName) {
return ResourceBundleStringMessages.Util.getLocaleFor(localeInfoName);
}
@Override
public FileStorageServiceDTO[] getAvailableFileStorageServices(String localeInfoName) {
Locale locale = ResourceBundleStringMessages.Util.getLocaleFor(localeInfoName);
List<FileStorageServiceDTO> serviceDtos = new ArrayList<>();
for (FileStorageService s : getService().getFileStorageManagementService().getAvailableFileStorageServices()) {
serviceDtos.add(FileStorageServiceDTOUtils.convert(s, locale));
serviceDtos.add(FileStorageServiceDTOUtils.convert(s, getLocale(localeInfoName)));
}
return serviceDtos.toArray(new FileStorageServiceDTO[0]);
}
@@ -5461,14 +5394,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public FileStorageServicePropertyErrorsDTO testFileStorageServiceProperties(String serviceName, String localeInfoName) {
Locale locale = ResourceBundleStringMessages.Util.getLocaleFor(localeInfoName);
try {
FileStorageService service = getFileStorageService(serviceName);
if (service != null) {
service.testProperties();
}
} catch (InvalidPropertiesException e) {
return FileStorageServiceDTOUtils.convert(e, locale);
return FileStorageServiceDTOUtils.convert(e, getLocale(localeInfoName));
}
return null;
}
@@ -5486,4 +5418,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
return null;
}
}
@Override
public void inviteCompetitorsForTrackingViaEmail(String serverUrlWithoutTrailingSlash, EventDTO eventDto,
String leaderboardName, Set<CompetitorDTO> competitorDtos, String localeInfoName) throws MailException {
Event event = getService().getEvent(eventDto.id);
Set<Competitor> competitors = new HashSet<>();
for (CompetitorDTO c : competitorDtos) {
competitors.add(getCompetitor(c));
}
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
getRaceLogTrackingAdapter().inviteCompetitorsForTrackingViaEmail(event, leaderboard, serverUrlWithoutTrailingSlash,
competitors, getLocale(localeInfoName));
}
}
@@ -82,7 +82,7 @@ public class StoreAndLoadDeviceIdentifierTest extends AbstractMongoDBTest {
private DeviceIdentifier storeAndLoad(DeviceIdentifier device, TypeBasedServiceFinderFactory forStoring, TypeBasedServiceFinderFactory forLoading) {
createFactories(forStoring);
Competitor c = new CompetitorImpl("a", "a", null, null, null);
Competitor c = new CompetitorImpl("a", "a", null, null, null, null);
raceLog.add(RaceLogEventFactory.INSTANCE.createDeviceCompetitorMappingEvent(now(), author, device,
c, 0, now(), now()));
@@ -174,7 +174,7 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
@Test
public void testStoreAndLoadDeviceCompetitorMappingEvent() {
DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
Competitor mappedTo = DomainFactory.INSTANCE.getOrCreateCompetitor("abc", "abc", null, null, null);
Competitor mappedTo = DomainFactory.INSTANCE.getOrCreateCompetitor("abc", "abc", null, null, null, null);
TimePoint from = new MillisecondsTimePoint(20);
TimePoint to = new MillisecondsTimePoint(30);
RaceLogDeviceCompetitorMappingEvent expectedEvent = eventFactory.createDeviceCompetitorMappingEvent(
@@ -251,7 +251,7 @@ public class StoreAndLoadRaceLogEventsTest extends AbstractMongoDBTest {
public void testStoreAndLoadRegisterCompetitorEvent() {
RaceLogRegisterCompetitorEvent expectedEvent = eventFactory.createRegisterCompetitorEvent(
expectedEventTime, author, expectedEventTime, expectedId, expectedPassId,
DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null));
DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null));
DBObject dbObject = mongoFactory.storeRaceLogEntry(logIdentifier, expectedEvent);
RaceLogRegisterCompetitorEvent actualEvent = loadEvent(dbObject);
@@ -58,7 +58,7 @@ public class StoreGPSFixTrackTest extends AbstractMongoDBTest {
public void testStoreAndLoadFixes() throws TransformationException, NoCorrespondingServiceRegisteredException {
TypeBasedServiceFinderFactory factory = new MockSmartphoneImeiServiceFinderFactory();
AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null);
Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null);
Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
MongoObjectFactory mongoObjectFactory = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService(), factory);
DomainObjectFactory domainObjectFactory = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE, factory);
@@ -627,7 +627,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
regattaStartDate, regattaEndDate, /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null);
List<Competitor> competitors = new ArrayList<Competitor>();
competitors.add(new CompetitorImpl("Axel", "Axel Uhl", Color.RED, null, null));
competitors.add(new CompetitorImpl("Axel", "Axel Uhl", Color.RED, null, null, null));
Iterable<Waypoint> waypoints = Collections.emptyList();
Course course = new CourseImpl("Course", waypoints);
@@ -113,15 +113,15 @@ public class TestStoringAndRetrievingLeaderboardGroups extends AbstractMongoDBTe
@Test
public void testStoringAndRetrievingLeaderboardGroupWithOverallLeaderboardWithScoreCorrection() throws NoWindException {
RacingEventService racingEventService = new RacingEventServiceImpl();
Competitor wolfgang = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")),
new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor wolfgang = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, null,
new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")), new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
final String raceColumnName1 = "My First Race 1";
MockedTrackedRaceWithFixedRankAndManyCompetitors raceWithTwoCompetitors = new MockedTrackedRaceWithFixedRankAndManyCompetitors(wolfgang, /* rank */ 1, /* started */ true);
raceWithTwoCompetitors.addCompetitor(hasso);
@@ -169,15 +169,15 @@ public class TestStoringAndRetrievingLeaderboardGroups extends AbstractMongoDBTe
@Test
public void testStoringAndRetrievingLeaderboardGroupWithSuppressedCompetitorsInOverallLeaderboard() {
Competitor wolfgang = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")),
new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor wolfgang = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, null,
new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")), new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
final String raceColumnName1 = "My First Race 1";
MockedTrackedRaceWithFixedRankAndManyCompetitors raceWithTwoCompetitors = new MockedTrackedRaceWithFixedRankAndManyCompetitors(wolfgang, /* rank */ 1, /* started */ true);
raceWithTwoCompetitors.addCompetitor(hasso);
@@ -225,15 +225,15 @@ public class TestStoringAndRetrievingLeaderboardGroups extends AbstractMongoDBTe
@Test
public void testStoringAndRetrievingLeaderboardGroupWithTwoSuppressedCompetitorsInOverallLeaderboard() {
Competitor wolfgang = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")),
new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor wolfgang = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, null,
new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")), new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
final String raceColumnName1 = "My First Race 1";
MockedTrackedRaceWithFixedRankAndManyCompetitors raceWithTwoCompetitors = new MockedTrackedRaceWithFixedRankAndManyCompetitors(wolfgang, /* rank */ 1, /* started */ true);
raceWithTwoCompetitors.addCompetitor(hasso);
@@ -76,11 +76,11 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
FlexibleLeaderboardImpl leaderboard = new FlexibleLeaderboardImpl(leaderboardName, new ThresholdBasedResultDiscardingRuleImpl(discardIndexResultsStartingWithHowManyRaces),
new LowPoint(), null);
Competitor wolfgang = createCompetitor();
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")),
new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor hasso = new CompetitorImpl(234, "Hasso Plattner", Color.RED, null,
new TeamImpl("STG", Collections.singleton(
new PersonImpl("Hasso Plattner", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Hasso Plattner")), new PersonImpl("Lutz Patrunky", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is Patty, the coach")), new BoatImpl("Dr. Hasso Plattner's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
final String raceColumnName1 = "My First Race 1";
MockedTrackedRaceWithFixedRankAndManyCompetitors raceWithTwoCompetitors = new MockedTrackedRaceWithFixedRankAndManyCompetitors(wolfgang, /* rank */ 1, /* started */ true);
raceWithTwoCompetitors.addCompetitor(hasso);
@@ -350,7 +350,7 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
final DomainFactory domainFactory = new DomainFactoryImpl();
// create the competitor through the competitor store/factory here so that the DomainObjectFactory finds it and
// resolves the score corrections appropriate
Competitor competitor = domainFactory.getOrCreateCompetitor(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, new TeamImpl("STG", Collections.singleton(
Competitor competitor = domainFactory.getOrCreateCompetitor(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, "someone@nowhere.de", new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
@@ -377,10 +377,10 @@ public class TestStoringAndRetrievingLeaderboards extends AbstractMongoDBTest {
}
private Competitor createCompetitor() {
Competitor competitor = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
Competitor competitor = new CompetitorImpl(123, "$$$Dr. Wolfgang+Hunger$$$", Color.RED, null, new TeamImpl("STG", Collections.singleton(
new PersonImpl("$$$Dr. Wolfgang+Hunger$$$", new NationalityImpl("GER"),
/* dateOfBirth */ null, "This is famous Dr. Wolfgang Hunger")), new PersonImpl("Rigo van Maas", new NationalityImpl("NED"),
/* dateOfBirth */ null, "This is Rigo, the coach")), new BoatImpl("Dr. Wolfgang Hunger's boat", new BoatClassImpl("505", /* typicallyStartsUpwind */ true), null));
return competitor;
}
@@ -277,7 +277,7 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
@Test
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogFinishPositioningConfirmedEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, null, null);
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, "someone@nowhere.de", null, null);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new com.sap.sse.common.Util.Triple<Serializable, String, MaxPointsReason>(storedCompetitor.getId(), storedCompetitor.getName(), MaxPointsReason.NONE));
@@ -346,7 +346,7 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
@Test
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogFinishPositioningListChangeEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, null, null);
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, "someone@nowhere.de", null, null);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new com.sap.sse.common.Util.Triple<Serializable, String, MaxPointsReason>(storedCompetitor.getId(), storedCompetitor.getName(), MaxPointsReason.NONE));
@@ -187,7 +187,7 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStorin
@Test
public void testStoreAndRetrieveRegattaWithRaceLogFinishPositioningListChangeEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, null, null);
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, "someone@nowhere.de", null, null);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new com.sap.sse.common.Util.Triple<Serializable, String, MaxPointsReason>(storedCompetitor.getId(), storedCompetitor.getName(), MaxPointsReason.NONE));
@@ -217,7 +217,7 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStorin
@Test
public void testStoreAndRetrieveRegattaWithRaceLogFinishPositioningConfirmedEvent() {
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, null, null);
Competitor storedCompetitor = DomainFactory.INSTANCE.getOrCreateCompetitor(UUID.randomUUID(), "SAP Extreme Sailing Team", Color.RED, "someone@nowhere.de", null, null);
CompetitorResults storedPositioningList = new CompetitorResultsImpl();
storedPositioningList.add(new com.sap.sse.common.Util.Triple<Serializable, String, MaxPointsReason>(storedCompetitor.getId(), storedCompetitor.getName(), MaxPointsReason.NONE));
@@ -91,8 +91,8 @@ public class PolarSheetGenerationTest {
settings, executor);
BoatClass forelle = new BoatClassImpl("Forelle", true);
Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", Color.RED, new TeamImpl("SAP", null, null),
new BoatImpl("Schnelle Forelle", forelle, "GER000"));
Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", Color.RED, null,
new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000"));
PolarFixAggregationWorker task = new PolarFixAggregationWorker(race,
resultContainer, startTime, endTime,
@@ -84,8 +84,7 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest {
List<String> races = table.getRaceNames();
assertThat(races.size(), equalTo(5));
assertThat(table.getEntries().size(), equalTo(0));
assertThat(table.getEntries().size(), equalTo(28)); // the regatta already has the races linked; regatta leaderboard obtains competitors from regatta
adminConsoleWindow.switchToWindow();
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration();
@@ -51,6 +51,8 @@ public class CompetitorJsonDeserializer implements JsonDeserializer<Competitor>
}
String name = (String) object.get(CompetitorJsonSerializer.FIELD_NAME);
String displayColorAsString = (String) object.get(CompetitorJsonSerializer.FIELD_DISPLAY_COLOR);
String email = (String) object.get(CompetitorJsonSerializer.FIELD_EMAIL);
final Color displayColor;
if (displayColorAsString == null || displayColorAsString.isEmpty()) {
displayColor = null;
@@ -67,7 +69,8 @@ public class CompetitorJsonDeserializer implements JsonDeserializer<Competitor>
boat = boatJsonDeserializer.deserialize(Helpers.getNestedObjectSafe(object,
CompetitorJsonSerializer.FIELD_BOAT));
}
Competitor competitor = competitorStore.getOrCreateCompetitor(competitorId, name, displayColor, team, boat);
Competitor competitor = competitorStore.getOrCreateCompetitor(competitorId, name, displayColor, email, team, boat);
return competitor;
} catch (Exception e) {
throw new JsonDeserializationException(e);
@@ -30,6 +30,7 @@ public class CompetitorJsonSerializer implements JsonSerializer<Competitor> {
public static final String FIELD_TEAM = "team";
public static final String FIELD_BOAT = "boat";
public static final String FIELD_DISPLAY_COLOR = "displayColor";
public static final String FIELD_EMAIL = "email";
private final JsonSerializer<Team> teamJsonSerializer;
private final JsonSerializer<Boat> boatJsonSerializer;
@@ -66,6 +67,7 @@ public class CompetitorJsonSerializer implements JsonSerializer<Competitor> {
}
result.put(FIELD_NAME, competitor.getName());
result.put(FIELD_DISPLAY_COLOR, competitor.getColor() == null ? null : competitor.getColor().getAsHtml());
result.put(FIELD_EMAIL, competitor.getEmail());
result.put(FIELD_SAILID, competitor.getBoat() == null ? "" : competitor.getBoat().getSailID());
final Nationality nationality = competitor.getTeam() == null ? null : competitor.getTeam().getNationality();
result.put(FIELD_NATIONALITY, nationality == null ? "" : nationality.getThreeLetterIOCAcronym());
@@ -237,7 +237,7 @@ public class RaceLogEventSerializerTest {
public void testRegisterCompetitorEventSerializer() {
// we use the real event type here because we do not want to re-implement the dispatching.
RaceLogEvent event = factory.createRegisterCompetitorEvent(null, author, 0,
DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null));
DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null));
serializer.serialize(event);
verify(registerCompetitorEventSerializer).serialize(event);
}
@@ -49,7 +49,7 @@ public class RegattaJsonSerializer implements JsonSerializer<Regatta> {
if(competitorSerializer != null) {
JSONArray competitorsJson = new JSONArray();
for (Competitor competitor: regatta.getCompetitors()) {
for (Competitor competitor: regatta.getAllCompetitors()) {
competitorsJson.add(competitorSerializer.serialize(competitor));
}
result.put(FIELD_COMPETITORS, competitorsJson);
Loaded 100 of 210 files, more files were not shown because too many files have changed in this diff. Show more