From 40f37d776aeb837021d0192ade5d7cea8102aa57 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 8 Jun 2017 11:26:28 +0200 Subject: [PATCH 01/13] Show message when removing series. --- .../adminconsole/RegattaDetailsComposite.java | 28 ++++++++++--------- .../sailing/gwt/ui/client/StringMessages.java | 1 + .../gwt/ui/client/StringMessages.properties | 1 + .../ui/client/StringMessages_de.properties | 3 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java index 99a26db6315..07bbcb5ba69 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaDetailsComposite.java @@ -238,19 +238,21 @@ public class RegattaDetailsComposite extends Composite { editRacesOfRegattaSeries(regatta, series); } else if (SeriesConfigImagesBarCell.ACTION_REMOVE.equals(value)) { RegattaIdentifier identifier = new RegattaName(regatta.getName()); - sailingService.removeSeries(identifier, series.getName(), new MarkedAsyncCallback( - new AsyncCallback() { - @Override - public void onFailure(Throwable cause) { - errorReporter.reportError("Error trying to remove series " + series.getName() - + ": " + cause.getMessage()); - } - - @Override - public void onSuccess(Void result) { - regattaRefresher.fillRegattas(); - } - })); + if (Window.confirm(stringMessages.reallyRemoveSeries(series.getName()))) { + sailingService.removeSeries(identifier, series.getName(), + new MarkedAsyncCallback(new AsyncCallback() { + @Override + public void onFailure(Throwable cause) { + errorReporter.reportError("Error trying to remove series " + series.getName() + + ": " + cause.getMessage()); + } + + @Override + public void onSuccess(Void result) { + regattaRefresher.fillRegattas(); + } + })); + } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 7208ae0e96a..15c478ce605 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1811,4 +1811,5 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String unknownLeaderboardType(String name); String selectCompetitorsToEliminate(); String trackedRaceAlreadyLinked(); + String reallyRemoveSeries(String seriesName); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 2e68ef6eca9..9fa71d85034 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -1790,3 +1790,4 @@ useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Use only unknownLeaderboardType=Unknown leaderboard type {0} selectCompetitorsToEliminate=Select competitors to eliminate trackedRaceAlreadyLinked=The race is already linked to a race column. Do you really want to change the link? +reallyRemoveSeries=Do you really want to remove the series ''{0}''? Note: all race logs for the attached race columns will also permanently be removed! diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index ad477ec0fc4..e1d168ffa84 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -1772,4 +1772,5 @@ showLiveNow="Jetzt live" anzeigen useOnlyOneOfStartTimeInferenceAndControlTrackingFromStartAndFinishTimes=Höchstens eine der Einstellungen "Startzeit aus Startlinienüberquerungen automatisch ableiten" und "Tracking durch Start- und Ende-Zeiten automatisch steuern" darf ausgewählt sein unknownLeaderboardType=Unbekannter Ranglistentyp {0} selectCompetitorsToEliminate=Zu eliminierende Teilnehmer auswählen -trackedRaceAlreadyLinked=Das Rennen ist bereits mit einer Renn-Spalte verlinkt. Wollen Sie die Verbindung wirklich ändern? \ No newline at end of file +trackedRaceAlreadyLinked=Das Rennen ist bereits mit einer Renn-Spalte verlinkt. Wollen Sie die Verbindung wirklich ändern? +reallyRemoveSeries=Möchten Sie die Serie ''{0}'' wirklich entfernen? Achtung: alle Ereignisprotokolle (RaceLogs) der zugehörigen Renn-Spalten werden unwiederbringlich gelöscht! \ No newline at end of file From 2d9d4d170f6e0d5be8aa55470f6fb8e50e55b5d1 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 20 Jun 2017 15:40:12 +0200 Subject: [PATCH 02/13] Adjusted Selenium test. --- .../pages/adminconsole/regatta/RegattaDetailsCompositePO.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java index ac75a0370d6..ff2252823c4 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java @@ -66,8 +66,8 @@ public class RegattaDetailsCompositePO extends PageArea { if (entry != null) { WebElement removeAction = ActionsHelper.findRemoveAction(entry.getWebElement()); removeAction.click(); - // ActionsHelper.acceptAlert(this.driver); - // waitForAjaxRequests(); + ActionsHelper.acceptAlert(this.driver); + waitForAjaxRequests(); } } From a12749d5e730e6fb56acdd49b50e671acf8cb520 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 26 Jun 2017 16:07:55 +0200 Subject: [PATCH 03/13] compileable attempt to serialize/deserialized Multipart content through replication Change-Id: I9ec088513d8a798444aeb334eae788cd14ccd0ac --- .../AbstractMailServiceReplicationTest.java | 2 +- .../src/com/sap/sse/mail/MailService.java | 5 ++- .../sap/sse/mail/impl/MailServiceImpl.java | 44 +++++++++++-------- .../sse/mail/impl/ReplicableMailService.java | 12 ++++- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java b/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java index f7d209626b2..a6980294bb2 100644 --- a/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java +++ b/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java @@ -34,7 +34,7 @@ public class AbstractMailServiceReplicationTest extends AbstractServerWithSingle }; mailService[0] = new MailServiceImpl(null, mailServiceResolver) { @Override - protected void internalSendMail(String toAddress, String subject, ContentSetter contentSetter) + protected void internalSendMail(String toAddress, String subject, MimeMessageConstructor mimeMessageConstructor) throws MailException { if (canSendMail) { Integer old = numberOfMailsSent.get(this); diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java index 95fbc3934c0..3742c48a1e9 100644 --- a/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java @@ -1,5 +1,8 @@ package com.sap.sse.mail; +import java.io.IOException; + +import javax.mail.MessagingException; import javax.mail.Multipart; import com.sap.sse.common.IsManagedByCache; @@ -29,5 +32,5 @@ public interface MailService extends ReplicableWithObjectInputStream s.internalSendMail(toAddress, subject, multipartContent)); + public void sendMail(String toAddress, String subject, Multipart multipartContent) throws MailException, IOException, MessagingException { + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + multipartContent.writeTo(bos); + apply(s -> s.internalSendMail(toAddress, subject, bos.toByteArray())); } @Override diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java index 116ae1f798c..1a92f35379b 100644 --- a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java @@ -1,12 +1,20 @@ package com.sap.sse.mail.impl; +import javax.mail.MessagingException; import javax.mail.Multipart; +import javax.mail.internet.MimeMessage; import com.sap.sse.common.mail.MailException; import com.sap.sse.mail.MailService; public interface ReplicableMailService extends MailService { - Void internalSendMail(String toAddress, String subject, String body) throws MailException; + Void internalSendMail(String toAddress, String subject, String body) throws MailException, MessagingException; - Void internalSendMail(String toAddress, String subject, Multipart multipartContent) throws MailException; + /** + * @param multipartContentAsByteArray + * the result of writing the {@link Multipart} object to a byte array output stream using + * {@link Multipart#writeTo(java.io.OutputStream)}. This can then be used to assemble a + * {@link MimeMessage} with {@link MimeMessage#MimeMessage(javax.mail.Session, java.io.InputStream)}. + */ + Void internalSendMail(String toAddress, String subject, byte[] multipartContentAsByteArray) throws MailException, MessagingException; } From dc66ad0e33efa927d3bd67e1eb68c4ba7c31c64f Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 26 Jun 2017 18:30:45 +0200 Subject: [PATCH 04/13] successful mail replication, from replica to master, for invitation Change-Id: Ic97945a1d6a1f04b94b743099b30285a189a51b1 --- .../impl/DomainObjectFactoryImpl.java | 2 +- .../impl/RaceLogTrackingAdapterImpl.java | 37 ++++------------ .../impl/NotificationMailTemplate.java | 12 ++++- .../impl/NotificationSetNotification.java | 31 ++++--------- .../AbstractMailServiceReplicationTest.java | 4 +- java/com.sap.sse.mail/META-INF/MANIFEST.MF | 1 + .../src/com/sap/sse/mail/MailService.java | 3 +- .../sse/mail/QRCodeMimeBodyPartSupplier.java | 44 +++++++++++++++++++ ...rializableDefaultMimeBodyPartSupplier.java | 36 +++++++++++++++ ...SerializableImageMimeBodyPartSupplier.java | 39 ++++++++++++++++ .../SerializableMimeBodyPartSupplier.java | 18 ++++++++ .../mail/SerializableMultipartSupplier.java | 33 ++++++++++++++ .../sap/sse/mail/impl/MailServiceImpl.java | 44 +++++++------------ .../sse/mail/impl/ReplicableMailService.java | 10 ++--- .../sap/sse/qrcode/QRCodeGenerationUtil.java | 2 +- 15 files changed, 225 insertions(+), 91 deletions(-) create mode 100755 java/com.sap.sse.mail/src/com/sap/sse/mail/QRCodeMimeBodyPartSupplier.java create mode 100755 java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableDefaultMimeBodyPartSupplier.java create mode 100755 java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableImageMimeBodyPartSupplier.java create mode 100755 java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMimeBodyPartSupplier.java create mode 100755 java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMultipartSupplier.java diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java index 3926f7317f9..b7b5702a4fe 100644 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java @@ -528,7 +528,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory { logger.info("Couldn't find regatta "+regattaName+" for corresponding regatta leaderboard. Not loading regatta leaderboard."); } else { result = new RegattaLeaderboardImpl(regatta, resultDiscardingRule); - result.setName(leaderboardName); + result.setName(leaderboardName); // this will temporarily set the display name; it will be adjusted later if a display name is found } return result; } diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java index a7e64e9d558..1925384c9a1 100755 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java @@ -1,7 +1,6 @@ package com.sap.sailing.domain.racelogtracking.impl; import java.io.IOException; -import java.io.InputStream; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -11,17 +10,10 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.StreamSupport; -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.impl.LastEventOfTypeFinder; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; @@ -73,7 +65,9 @@ import com.sap.sse.common.mail.MailException; import com.sap.sse.common.media.MediaTagConstants; import com.sap.sse.i18n.ResourceBundleStringMessages; import com.sap.sse.mail.MailService; -import com.sap.sse.qrcode.QRCodeGenerationUtil; +import com.sap.sse.mail.QRCodeMimeBodyPartSupplier; +import com.sap.sse.mail.SerializableDefaultMimeBodyPartSupplier; +import com.sap.sse.mail.SerializableMultipartSupplier; import com.sap.sse.shared.media.ImageDescriptor; import com.sap.sse.util.impl.NonGwtUrlHelper; @@ -322,9 +316,6 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter { final ResourceBundleStringMessages B = RaceLogTrackingI18n.STRING_MESSAGES; String subject = String.format("%s %s", B.get(locale, "trackingInvitationFor"), invitee); - // taken from http://www.tutorialspoint.com/javamail_api/javamail_api_send_inlineimage_in_email.htm - BodyPart messageTextPart = new MimeBodyPart(); - boolean hasIOSAppUrl = iOSAppUrl != null && !iOSAppUrl.isEmpty(); boolean hasAndroidAppUrl = androidAppUrl != null && !androidAppUrl.isEmpty(); boolean hasLogoUrl = logoUrl != null && !logoUrl.isEmpty(); @@ -373,26 +364,16 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter { htmlText.append(""); try { - messageTextPart.setContent(htmlText.toString(), "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", ""); - messageImagePart.setHeader("Content-Disposition", "inline;filename=\"qr.png\""); - - MimeMultipart multipart = new MimeMultipart(); - multipart.addBodyPart(messageTextPart); - multipart.addBodyPart(messageImagePart); - - getMailService().sendMail(toAddress, subject, multipart); - } catch (MessagingException | MailException | WriterException | IOException e) { + final SerializableMultipartSupplier multipartSupplier = new SerializableMultipartSupplier("Invite", + new SerializableDefaultMimeBodyPartSupplier(htmlText.toString(), "text/html"), + new QRCodeMimeBodyPartSupplier(url)); + getMailService().sendMail(toAddress, subject, multipartSupplier); + } catch (MessagingException | MailException | IOException e) { logger.log(Level.SEVERE, "Error trying to send mail to " + invitee + " with e-mail address " + toAddress, e); throw new MailException(e.getMessage()); } } - + @Override public void inviteBuoyTenderViaEmail(Event event, Leaderboard leaderboard, String serverUrlWithoutTrailingSlash, String emails, String iOSAppUrl, String androidAppUrl, Locale locale) throws MailException { diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationMailTemplate.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationMailTemplate.java index 27d6b5a67ee..38121b3e96b 100644 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationMailTemplate.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationMailTemplate.java @@ -1,12 +1,20 @@ package com.sap.sailing.server.notification.impl; +import java.io.Serializable; import java.net.URL; import java.util.Arrays; import com.sap.sse.common.Util.Pair; -public class NotificationMailTemplate { - +/** + * The class needs to implement the {@link Serializable} interface because it can become part of a + * {@link SerializableMultipartSupplier}. + * + * @author Axel Uhl (D043530) + * + */ +public class NotificationMailTemplate implements Serializable { + private static final long serialVersionUID = 3291811210425722552L; private final String subject; private final String title; private final String text; diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationSetNotification.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationSetNotification.java index f61077ac829..d03c67e5033 100644 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationSetNotification.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/notification/impl/NotificationSetNotification.java @@ -10,17 +10,12 @@ import java.util.Locale; 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.Multipart; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMultipart; -import javax.mail.util.ByteArrayDataSource; - import com.sap.sse.common.Util.Pair; import com.sap.sse.i18n.impl.ResourceBundleStringMessagesImpl; import com.sap.sse.mail.MailService; +import com.sap.sse.mail.SerializableDefaultMimeBodyPartSupplier; +import com.sap.sse.mail.SerializableImageMimeBodyPartSupplier; +import com.sap.sse.mail.SerializableMultipartSupplier; import com.sap.sse.mail.queue.MailNotification; import com.sap.sse.security.PreferenceObjectBasedNotificationSet; import com.sap.sse.security.User; @@ -81,22 +76,12 @@ public abstract class NotificationSetNotification implements MailNotification // send batches with the actual mail addresses as bcc? associatedNotificationSet.forUsersWithVerifiedEmailMappedTo(objectToNotifyAbout, (user) -> { Locale locale = user.getLocaleOrDefault(); - Multipart multipart = new MimeMultipart("related"); - BodyPart bodyPart = new MimeBodyPart(); - BodyPart messageImagePart = new MimeBodyPart(); + final NotificationMailTemplate mailTemplate = getMailTemplate(objectToNotifyAbout, locale); try { - // TODO: add cid:saplogo - NotificationMailTemplate mailTemplate = getMailTemplate(objectToNotifyAbout, locale); - bodyPart.setContent(getMailContent(mailTemplate, user, locale), "text/html"); - multipart.addBodyPart(bodyPart); - - DataSource imageDs = new ByteArrayDataSource(LOGO_BYTES, "image/png"); - messageImagePart.setDataHandler(new DataHandler(imageDs)); - messageImagePart.setHeader("Content-ID", "saplogo"); - messageImagePart.setHeader("Content-Disposition", "inline;filename=\"saplogo.png\""); - multipart.addBodyPart(messageImagePart); - - mailService.sendMail(user.getEmail(), mailTemplate.getSubject(), multipart); + final SerializableMultipartSupplier multipartSupplier = new SerializableMultipartSupplier("related", + new SerializableDefaultMimeBodyPartSupplier(getMailContent(mailTemplate, user, locale), "text/html"), + new SerializableImageMimeBodyPartSupplier(LOGO_BYTES, "image/png", "saplogo", "saplogo.png")); + mailService.sendMail(user.getEmail(), mailTemplate.getSubject(), multipartSupplier); } catch (Exception e) { logger.log(Level.SEVERE, "Could not send mail notification for \"" + objectToNotifyAbout + "\" to user \"" + user + "\"", e); diff --git a/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java b/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java index a6980294bb2..9d0ef53af28 100644 --- a/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java +++ b/java/com.sap.sse.mail.replication.testsupport/src/com/sap/sse/mail/replication/testsupport/AbstractMailServiceReplicationTest.java @@ -8,6 +8,7 @@ import org.junit.Before; import com.sap.sse.common.mail.MailException; import com.sap.sse.mail.MailService; import com.sap.sse.mail.MailServiceResolver; +import com.sap.sse.mail.SerializableMultipartSupplier; import com.sap.sse.mail.impl.MailServiceImpl; import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp; import com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest; @@ -34,12 +35,13 @@ public class AbstractMailServiceReplicationTest extends AbstractServerWithSingle }; mailService[0] = new MailServiceImpl(null, mailServiceResolver) { @Override - protected void internalSendMail(String toAddress, String subject, MimeMessageConstructor mimeMessageConstructor) + public Void internalSendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException { if (canSendMail) { Integer old = numberOfMailsSent.get(this); numberOfMailsSent.put(this, old == null ? 1 : old + 1); } + return null; } }; return mailService[0]; diff --git a/java/com.sap.sse.mail/META-INF/MANIFEST.MF b/java/com.sap.sse.mail/META-INF/MANIFEST.MF index ab125af96f5..f78820d7d6a 100755 --- a/java/com.sap.sse.mail/META-INF/MANIFEST.MF +++ b/java/com.sap.sse.mail/META-INF/MANIFEST.MF @@ -12,6 +12,7 @@ Export-Package: com.sap.sse.mail, com.sap.sse.mail.queue.impl Import-Package: javax.mail, javax.mail.internet, + javax.mail.util;version="1.4.0", org.osgi.framework, org.osgi.util.tracker;version="1.5.1" Require-Bundle: com.sap.sse.replication, diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java index 3742c48a1e9..100f5a1e848 100644 --- a/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/MailService.java @@ -3,7 +3,6 @@ package com.sap.sse.mail; import java.io.IOException; import javax.mail.MessagingException; -import javax.mail.Multipart; import com.sap.sse.common.IsManagedByCache; import com.sap.sse.common.mail.MailException; @@ -32,5 +31,5 @@ public interface MailService extends ReplicableWithObjectInputStream"); + messageImagePart.setHeader("Content-Disposition", "inline;filename=\"qr.png\""); + return messageImagePart; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableDefaultMimeBodyPartSupplier.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableDefaultMimeBodyPartSupplier.java new file mode 100755 index 00000000000..d039ab07a51 --- /dev/null +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableDefaultMimeBodyPartSupplier.java @@ -0,0 +1,36 @@ +package com.sap.sse.mail; + +import java.io.Serializable; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; + +/** + * Can construct a {@link MimeBodyPart} out of a serializable object and a content type specification string. + * + * @author Axel Uhl (D043530) + * + */ +public class SerializableDefaultMimeBodyPartSupplier implements SerializableMimeBodyPartSupplier { + private static final long serialVersionUID = -2893291156595020570L; + private final Serializable serializableContent; + private final String contentType; + + public SerializableDefaultMimeBodyPartSupplier(Serializable serializableContent, String contentType) { + super(); + this.serializableContent = serializableContent; + this.contentType = contentType; + } + + @Override + public MimeBodyPart get() { + final MimeBodyPart result = new MimeBodyPart(); + try { + result.setContent(serializableContent, contentType); + } catch (MessagingException e) { + throw new RuntimeException(e); + } + return result; + } + +} diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableImageMimeBodyPartSupplier.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableImageMimeBodyPartSupplier.java new file mode 100755 index 00000000000..d2715f4baad --- /dev/null +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableImageMimeBodyPartSupplier.java @@ -0,0 +1,39 @@ +package com.sap.sse.mail; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.util.ByteArrayDataSource; + +public class SerializableImageMimeBodyPartSupplier implements SerializableMimeBodyPartSupplier { + private static final long serialVersionUID = -1540223936240644379L; + private final byte[] imageBytes; + private final String contentType; + private final String contentId; + private final String imageFilename; + + public SerializableImageMimeBodyPartSupplier(byte[] imageBytes, String contentType, String contentId, + String imageFilename) { + super(); + this.imageBytes = imageBytes; + this.contentType = contentType; + this.contentId = contentId; + this.imageFilename = imageFilename; + } + + @Override + public MimeBodyPart get() { + final MimeBodyPart messageImagePart = new MimeBodyPart(); + DataSource imageDs = new ByteArrayDataSource(imageBytes, contentType); + try { + messageImagePart.setDataHandler(new DataHandler(imageDs)); + messageImagePart.setHeader("Content-ID", contentId); + messageImagePart.setHeader("Content-Disposition", "inline;filename=\"" + imageFilename + "\""); + return messageImagePart; + } catch (MessagingException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMimeBodyPartSupplier.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMimeBodyPartSupplier.java new file mode 100755 index 00000000000..4d5f06f78ac --- /dev/null +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMimeBodyPartSupplier.java @@ -0,0 +1,18 @@ +package com.sap.sse.mail; + +import java.io.Serializable; +import java.util.function.Supplier; + +import javax.mail.Multipart; +import javax.mail.internet.MimeBodyPart; + +/** + * Plays together with {@link SerializableMultipartSupplier}. One or more instances of this type can be + * passed to its constructor so that after de-serialization a {@link Multipart} message can be constructed + * from the parts. + * + * @author Axel Uhl (D043530) + * + */ +public interface SerializableMimeBodyPartSupplier extends Supplier, Serializable { +} diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMultipartSupplier.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMultipartSupplier.java new file mode 100755 index 00000000000..603683a3290 --- /dev/null +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/SerializableMultipartSupplier.java @@ -0,0 +1,33 @@ +package com.sap.sse.mail; + +import java.util.function.Supplier; + +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.internet.MimeMultipart; + +import com.sap.sse.common.Named; +import com.sap.sse.common.impl.NamedImpl; + +public class SerializableMultipartSupplier extends NamedImpl implements Supplier, Named { + private static final long serialVersionUID = 4316486727705670702L; + private final SerializableMimeBodyPartSupplier[] bodyPartSuppliers; + + public SerializableMultipartSupplier(String name, SerializableMimeBodyPartSupplier... partSuppliers) { + super(name); + this.bodyPartSuppliers = partSuppliers; + } + + @Override + public Multipart get() { + final Multipart result = new MimeMultipart(getName()); + for (final SerializableMimeBodyPartSupplier bodyPartSupplier : bodyPartSuppliers) { + try { + result.addBodyPart(bodyPartSupplier.get()); + } catch (MessagingException e) { + throw new RuntimeException(e); + } + } + return result; + } +} diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java index bcac4508275..526b8a0c3e3 100644 --- a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/MailServiceImpl.java @@ -1,7 +1,5 @@ package com.sap.sse.mail.impl; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; @@ -19,7 +17,6 @@ import java.util.logging.Logger; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; -import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; @@ -30,6 +27,7 @@ import javax.mail.internet.MimeUtility; import com.sap.sse.common.IsManagedByCache; import com.sap.sse.common.mail.MailException; import com.sap.sse.mail.MailServiceResolver; +import com.sap.sse.mail.SerializableMultipartSupplier; import com.sap.sse.replication.OperationExecutionListener; import com.sap.sse.replication.OperationWithResult; import com.sap.sse.replication.ReplicationMasterDescriptor; @@ -67,20 +65,20 @@ public class MailServiceImpl implements ReplicableMailService { } } - protected static interface MimeMessageConstructor extends Serializable { - MimeMessage createMimeMessage(Session session) throws MessagingException; + protected static interface ContentSetter { + void setContent(MimeMessage msg) throws MessagingException; } - + private boolean canSendMail() { return mailProperties != null && mailProperties.containsKey("mail.transport.protocol"); } // protected for testing purposes - protected void internalSendMail(String toAddress, String subject, MimeMessageConstructor mimeMessageConstructor) throws MailException, MessagingException { + protected void internalSendMail(String toAddress, String subject, ContentSetter contentSetter) throws MailException { if (canSendMail()) { if (toAddress != null) { Session session = Session.getInstance(mailProperties, new SMTPAuthenticator()); - MimeMessage msg = mimeMessageConstructor.createMimeMessage(session); + MimeMessage msg = new MimeMessage(session); ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { msg.setFrom(new InternetAddress(mailProperties.getProperty("mail.from", "root@sapsailing.com"))); @@ -93,6 +91,7 @@ public class MailServiceImpl implements ReplicableMailService { // this fixes the DCH MIME type error // see http://tanyamadurapperuma.blogspot.de/2014/01/struggling-with-nosuchproviderexception.html Thread.currentThread().setContextClassLoader(javax.mail.Session.class.getClassLoader()); + contentSetter.setContent(msg); // for testing with gmail //Transport ts = session.getTransport("smtps"); Transport ts = session.getTransport(); @@ -115,15 +114,11 @@ public class MailServiceImpl implements ReplicableMailService { } @Override - public Void internalSendMail(String toAddress, String subject, String body) throws MailException, MessagingException { - internalSendMail(toAddress, subject, new MimeMessageConstructor() { - private static final long serialVersionUID = 1143693344101301674L; - + public Void internalSendMail(String toAddress, String subject, String body) throws MailException { + internalSendMail(toAddress, subject, new ContentSetter() { @Override - public MimeMessage createMimeMessage(Session session) throws MessagingException { - final MimeMessage result = new MimeMessage(session); - result.setContent(body, "text/plain"); - return result; + public void setContent(MimeMessage msg) throws MessagingException { + msg.setContent(body, "text/plain"); } }); return null; @@ -135,24 +130,19 @@ public class MailServiceImpl implements ReplicableMailService { } @Override - public Void internalSendMail(String toAddress, String subject, final byte[] multipartContentAsByteArray) throws MailException, MessagingException { - internalSendMail(toAddress, subject, new MimeMessageConstructor() { - private static final long serialVersionUID = -3874896927287907321L; - + public Void internalSendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException { + internalSendMail(toAddress, subject, new ContentSetter() { @Override - public MimeMessage createMimeMessage(Session session) throws MessagingException { - final MimeMessage result = new MimeMessage(session, new ByteArrayInputStream(multipartContentAsByteArray)); - return result; + public void setContent(MimeMessage msg) throws MessagingException { + msg.setContent(multipartSupplier.get()); } }); return null; } @Override - public void sendMail(String toAddress, String subject, Multipart multipartContent) throws MailException, IOException, MessagingException { - final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - multipartContent.writeTo(bos); - apply(s -> s.internalSendMail(toAddress, subject, bos.toByteArray())); + public void sendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException { + apply(s -> s.internalSendMail(toAddress, subject, multipartSupplier)); } @Override diff --git a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java index 1a92f35379b..ba377862b15 100644 --- a/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java +++ b/java/com.sap.sse.mail/src/com/sap/sse/mail/impl/ReplicableMailService.java @@ -2,19 +2,17 @@ package com.sap.sse.mail.impl; import javax.mail.MessagingException; import javax.mail.Multipart; -import javax.mail.internet.MimeMessage; import com.sap.sse.common.mail.MailException; import com.sap.sse.mail.MailService; +import com.sap.sse.mail.SerializableMultipartSupplier; public interface ReplicableMailService extends MailService { Void internalSendMail(String toAddress, String subject, String body) throws MailException, MessagingException; /** - * @param multipartContentAsByteArray - * the result of writing the {@link Multipart} object to a byte array output stream using - * {@link Multipart#writeTo(java.io.OutputStream)}. This can then be used to assemble a - * {@link MimeMessage} with {@link MimeMessage#MimeMessage(javax.mail.Session, java.io.InputStream)}. + * @param multipartSupplier + * can produce a {@link Multipart} object and must be serializable */ - Void internalSendMail(String toAddress, String subject, byte[] multipartContentAsByteArray) throws MailException, MessagingException; + Void internalSendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException, MessagingException; } diff --git a/java/com.sap.sse/src/com/sap/sse/qrcode/QRCodeGenerationUtil.java b/java/com.sap.sse/src/com/sap/sse/qrcode/QRCodeGenerationUtil.java index b4353f7139a..4ae986db449 100644 --- a/java/com.sap.sse/src/com/sap/sse/qrcode/QRCodeGenerationUtil.java +++ b/java/com.sap.sse/src/com/sap/sse/qrcode/QRCodeGenerationUtil.java @@ -27,7 +27,7 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; * */ public class QRCodeGenerationUtil { - public static InputStream create(String text, int sizeInPixels) throws WriterException, IOException { + public static InputStream create(String text, int sizeInPixels) throws Exception { Hashtable hintMap = new Hashtable(); hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); From 4815b40294fd66e7b20541e0f69c3e9a992dfa6d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Jun 2017 09:31:09 +0200 Subject: [PATCH 05/13] switched SwissTiming tests to ota2.sportresult.com and "un-ignored" them again Change-Id: Ifcb466de8e288e38191ad4c7f5259deb718378c9 --- .../test/SwissTimingRaceConfigurationTest.java | 2 -- .../test/SwissTimingReplayAdapterServiceTest.java | 6 ++---- .../impl/SwissTimingReplayServiceImpl.java | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingRaceConfigurationTest.java b/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingRaceConfigurationTest.java index 2018dc05779..9aadcc9abaf 100644 --- a/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingRaceConfigurationTest.java +++ b/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingRaceConfigurationTest.java @@ -41,7 +41,6 @@ public class SwissTimingRaceConfigurationTest { } } - @Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19") @Test public void testRaceConfig_446483_no_detail_config() throws Exception { URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "446483")); @@ -59,7 +58,6 @@ public class SwissTimingRaceConfigurationTest { } - @Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19") @Test public void testRaceConfig_6260_with_detail_config() throws Exception { URL configFileURL = new URL(MessageFormat.format(SwissTimingReplayServiceImpl.RACE_CONFIG_URL_TEMPLATE, "6260")); diff --git a/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingReplayAdapterServiceTest.java b/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingReplayAdapterServiceTest.java index e067deb4674..63148dc1c45 100644 --- a/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingReplayAdapterServiceTest.java +++ b/java/com.sap.sailing.domain.swisstimingreplayadapter.test/src/com/sap/sailing/domain/swisstimingreplayadapter/test/SwissTimingReplayAdapterServiceTest.java @@ -74,12 +74,11 @@ public class SwissTimingReplayAdapterServiceTest { assertEquals(321920, replayCountListener.rankingMarkCount); } - @Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19") @Test public void testRaceData_SAW005905_20120805_EqualsOnlineVersion() throws Exception { byte[] localCopy = read(getClass().getResourceAsStream("/SAW005905.20120805.replay")); byte[] onlineCopy = read((InputStream) new URL( - "http://live.ota.st-sportservice.com/Replay?id=446495&_start=0").getContent()); + "http://ota2.sportresult.com/Replay?id=446495&_start=0").getContent()); assertArrayEquals(localCopy, onlineCopy); } @@ -114,13 +113,12 @@ public class SwissTimingReplayAdapterServiceTest { assertEquals(9500, replayCountListener.rankingMarkCount); } - @Ignore("According to Radek Masnica ('masnica.r@st-software.com') the OTA stuff may not be supported any longer by the SwissTiming Leipzip lab... 2017-05-19") @Test public void testRaceData_SAW005905_20120805_online() throws Exception { SwissTimingReplayTestListener replayCountListener = new SwissTimingReplayTestListener(); // race ID is 450053, as extracted from http://live.ota.st-sportservice.com/service?cmd=unity_race_overview&id=91 byte[] onlineCopy = read((InputStream) new URL( - "http://live.ota.st-sportservice.com/Replay?id=446495&_start=0").getContent()); + "http://ota2.sportresult.com/Replay?id=446495&_start=0").getContent()); new SwissTimingReplayParserImpl().readData(new ByteArrayInputStream(onlineCopy), replayCountListener); assertEquals(0, replayCountListener.keyFrameIndexSum); assertEquals(715, replayCountListener.keyFrameIndexPositionCount); diff --git a/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayServiceImpl.java b/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayServiceImpl.java index 70d9e58470a..5863c666e57 100644 --- a/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayServiceImpl.java +++ b/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/impl/SwissTimingReplayServiceImpl.java @@ -34,7 +34,7 @@ import com.sap.sse.util.ByteArrayOutputStreamWithVisibleBuffer; public class SwissTimingReplayServiceImpl implements SwissTimingReplayService { - public static final String RACE_CONFIG_URL_TEMPLATE = "http://live.ota.st-sportservice.com/configuration?_race={0}&effective=1&additional=config"; + public static final String RACE_CONFIG_URL_TEMPLATE = "http://ota2.sportresult.com/configuration?_race={0}&effective=1&additional=config"; private static final String SWISSTIMING_DATEFORMAT_PATTERN = "dd.MM.yyyy HH:mm"; private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getTimeZone("GMT"); From 43558fb07126fa31d50657808e31c339712eb36c Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Jun 2017 09:31:54 +0200 Subject: [PATCH 06/13] removed non-sensical test Change-Id: I26a7c72ab740e3245d7e7e76a2b5c134ed24e1f4 --- .../swisstimingadapter/impl/DomainFactoryTest.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java index 64c8053f107..81770b1428e 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java @@ -53,14 +53,4 @@ public class DomainFactoryTest { assertThat(raceType, is(notNullValue())); assertThat(raceType.getRaceCode(), is(OlympicRaceCode.UNKNOWN)); } - - @Ignore - @Test - public void testCompetitorLookup() throws Exception { - before(); - -// swissTimingDomainFactory.getOrCreateCompetitor(boatID, threeLetterIOCCode, name, boatClass); - - } - } From 6f11e2f199a85fa588c340df8e68626f3ced65af Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Tue, 27 Jun 2017 10:09:02 +0200 Subject: [PATCH 07/13] consolidated imports to avoid warnings Change-Id: I9d828e4f7d701540fa9269f483d715de36069eed --- .../domain/swisstimingadapter/impl/DomainFactoryTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java index 81770b1428e..d0b8258ac10 100644 --- a/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java +++ b/java/com.sap.sailing.domain.swisstimingadapter.test/src/com/sap/sailing/domain/swisstimingadapter/impl/DomainFactoryTest.java @@ -5,7 +5,6 @@ import static org.hamcrest.core.IsNull.notNullValue; import static org.junit.Assert.assertThat; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import com.sap.sailing.domain.swisstimingadapter.RaceType; From 524bcd125972ed42072a5c7d9b63c0b34af36834 Mon Sep 17 00:00:00 2001 From: Kai Boernert Date: Tue, 27 Jun 2017 17:19:20 +0200 Subject: [PATCH 08/13] use quickrankprovider from leaderboard for liveracemap --- .../LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java | 5 +++++ .../sailing/gwt/autoplay/client/utils/AutoplayHelper.java | 7 ++++--- .../sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java | 5 ++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java index cc3e12fbd47..01ce293790a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java @@ -20,7 +20,9 @@ import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings; import com.sap.sailing.gwt.settings.client.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.client.shared.racemap.RaceCompetitorSet; import com.sap.sailing.gwt.ui.leaderboard.LeaderboardEntryPoint; +import com.sap.sailing.gwt.ui.raceboard.QuickRanksDTOFromLeaderboardDTOProvider; import com.sap.sailing.gwt.ui.shared.WindDTO; import com.sap.sailing.gwt.ui.shared.WindTrackInfoDTO; import com.sap.sse.gwt.client.ErrorReporter; @@ -154,6 +156,9 @@ public class LiveRaceWithRacemapAndLeaderBoardPresenterImpl true, lifeRace, getPlace().getRaceMapSelectionProvider(), timer, null, getSlideCtx().getContextDefinition().getLeaderboardName(), errorReporter, StringMessages.INSTANCE, null, false, null, false, null, false, true, false, false, false); + + getPlace().getRaceMap().setQuickRanksDTOProvider(new QuickRanksDTOFromLeaderboardDTOProvider(new RaceCompetitorSet(getPlace().getRaceMapSelectionProvider()), lifeRace)); + view.startingWith(this, panel, getPlace().getRaceMap(), leaderboardPanel); selectionTimer.schedule(SWITCH_COMPETITOR_DELAY); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java index 1b3dff470b2..52027a3ace7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java @@ -31,6 +31,7 @@ import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapResources; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapSettings; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings; import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes; +import com.sap.sailing.gwt.ui.raceboard.AbstractQuickRanksDTOProvider; import com.sap.sailing.gwt.ui.shared.EventDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO; @@ -203,7 +204,7 @@ public class AutoplayHelper { AutoplayHelper.asyncActionsExecutor, errorReporter, raceboardTimer, callback, clientTimeWhenResponseWasReceived, serverTimeDuringRequest, clientTimeWhenRequestWasSent, - raceTimesInfo); + raceTimesInfo,new DefaultQuickRanksDTOProvider()); } @Override @@ -261,7 +262,7 @@ public class AutoplayHelper { Iterable competitors, SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, ErrorReporter errorReporter, Timer raceboardTimer, AsyncCallback callback, long clientTimeWhenResponseWasReceived, Date serverTimeDuringRequest, - long clientTimeWhenRequestWasSent, Map raceTimesInfos) { + long clientTimeWhenRequestWasSent, Map raceTimesInfos,AbstractQuickRanksDTOProvider provider) { ArrayList typesToConsiderOnZoom = new ArrayList<>(); // Other zoom types such as BOATS, TAILS or WINDSENSORS are not currently used as default zoom types. @@ -282,7 +283,7 @@ public class AutoplayHelper { RaceMap raceboardPerspective = new RaceMap(null, null, raceMapLifecycle, settings, sailingService, asyncActionsExecutor, errorReporter, raceboardTimer, competitorSelectionProvider, new RaceCompetitorSet(competitorSelectionProvider), StringMessages.INSTANCE, currentLiveRace, - raceMapResources, false, new DefaultQuickRanksDTOProvider()); + raceMapResources, false,provider); raceboardPerspective.raceTimesInfosReceived(raceTimesInfos, clientTimeWhenRequestWasSent, serverTimeDuringRequest, clientTimeWhenResponseWasReceived); // raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceboardPerspective); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java index 3f751ba7fc2..2ba771cae61 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java @@ -353,7 +353,7 @@ public class RaceMap extends AbstractCompositeComponent impleme * quick ranks received from a {@link RaceMapDataDTO#quickRanks} field but may choose to ignore this information, e.g., * if it can assume that more current information about ranks and leg numbers is available from a {@link LeaderboardDTO}. */ - private final QuickRanksDTOProvider quickRanksDTOProvider; + private QuickRanksDTOProvider quickRanksDTOProvider; private final CombinedWindPanel combinedWindPanel; private final TrueNorthIndicatorPanel trueNorthIndicatorPanel; @@ -487,6 +487,9 @@ public class RaceMap extends AbstractCompositeComponent impleme this.setSize("100%", "100%"); } + public void setQuickRanksDTOProvider(QuickRanksDTOProvider quickRanksDTOProvider) { + this.quickRanksDTOProvider = quickRanksDTOProvider; + } /** * The {@link WindDTO#dampenedTrueWindFromDeg} direction if {@link #lastCombinedWindTrackInfoDTO} has a * {@link WindSourceType#COMBINED} source which has at least one fix recorded; null otherwise. From 40261815bd12320d8945ac972ae3208580867eda Mon Sep 17 00:00:00 2001 From: Papick Garcia Taboada Date: Wed, 28 Jun 2017 10:40:19 +0200 Subject: [PATCH 09/13] Fixed wrong assignment, introduced nullToEmptyMap --- .../racemap/DefaultQuickRanksDTOProvider.java | 13 +++++++------ .../gwt/ui/client/shared/racemap/RaceMap.java | 3 ++- .../src/com/sap/sse/common/Util.java | 12 +++++++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/DefaultQuickRanksDTOProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/DefaultQuickRanksDTOProvider.java index 5b29028a947..ef2ef86f495 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/DefaultQuickRanksDTOProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/DefaultQuickRanksDTOProvider.java @@ -1,5 +1,6 @@ package com.sap.sailing.gwt.ui.client.shared.racemap; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; @@ -8,13 +9,13 @@ import com.sap.sailing.gwt.ui.shared.QuickRankDTO; import com.sap.sse.common.Util; public class DefaultQuickRanksDTOProvider extends AbstractQuickRanksDTOProvider { - private Map quickRanksFromServer; + private Map currentQuickRanksFromServer = Collections.emptyMap(); @Override - public void quickRanksReceivedFromServer(Map quickRanksFromServer) { - final Map oldQuickRanksFromServer = quickRanksFromServer; - this.quickRanksFromServer = quickRanksFromServer; - for (final Entry e : quickRanksFromServer.entrySet()) { + public void quickRanksReceivedFromServer(Map receivedQuickRanksFromServer) { + final Map oldQuickRanksFromServer = this.currentQuickRanksFromServer; + this.currentQuickRanksFromServer = Util.nullToEmptyMap(receivedQuickRanksFromServer); + for (final Entry e : currentQuickRanksFromServer.entrySet()) { final QuickRankDTO oldQuickRank = oldQuickRanksFromServer.get(e.getKey()); if (Util.equalsWithNull(oldQuickRank, e.getValue())) { notifyListeners(e.getKey(), oldQuickRank, e.getValue()); @@ -24,7 +25,7 @@ public class DefaultQuickRanksDTOProvider extends AbstractQuickRanksDTOProvider @Override public Map getQuickRanks() { - return quickRanksFromServer; + return currentQuickRanksFromServer; } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java index 96aa3a7cd92..f90b0439a93 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java @@ -1400,7 +1400,8 @@ public class RaceMap extends AbstractCompositeComponent impleme final static Distance advantageLineLength = new MeterDistance(1000); // TODO this should probably rather scale with the visible area of the map; bug 616 private void showAdvantageLine(Iterable competitorsToShow, Date date, long timeForPositionTransitionMillis) { - if (map != null && lastRaceTimesInfo != null && quickRanksDTOProvider.getQuickRanks() != null && lastCombinedWindTrackInfoDTO != null) { + if (map != null && lastRaceTimesInfo != null && quickRanksDTOProvider.getQuickRanks().isEmpty() + && lastCombinedWindTrackInfoDTO != null) { boolean drawAdvantageLine = false; if (settings.getHelpLinesSettings().isVisible(HelpLineTypes.ADVANTAGELINE)) { // find competitor with highest rank diff --git a/java/com.sap.sse.common/src/com/sap/sse/common/Util.java b/java/com.sap.sse.common/src/com/sap/sse/common/Util.java index d358e28eb08..b03ed20381e 100755 --- a/java/com.sap.sse.common/src/com/sap/sse/common/Util.java +++ b/java/com.sap.sse.common/src/com/sap/sse/common/Util.java @@ -514,7 +514,7 @@ public class Util { * {@link #isEmpty(Iterable) isEmpty(splitAlongWhitespaceRespectingDoubleQuotedPhrases(" \n\t ")) * * - * @return if {@code s==null}, then {@code null}, else a non-{@code null} but possibly empty sequence of {@link Strings} whose iteration order corresponds with + * @return if {@code s==null}, then {@code null}, else a non-{@code null} but possibly empty sequence of {@link String} whose iteration order corresponds with * the occurrence of the split results, left to right, in {@code s} */ public static Iterable splitAlongWhitespaceRespectingDoubleQuotedPhrases(String s) { @@ -734,4 +734,14 @@ public class Util { public static > T max(T... elements) { return Collections.max(Arrays.asList(elements)); } + + /** + * Checks if the given map is null, and if, returns an empty map. + */ + public static Map nullToEmptyMap(Map map) { + if (map == null) { + return Collections.emptyMap(); + } + return map; + } } \ No newline at end of file From b69df0c2656c44c9f223330a59c1a178ec49906c Mon Sep 17 00:00:00 2001 From: Kai Boernert Date: Wed, 28 Jun 2017 10:48:38 +0200 Subject: [PATCH 10/13] fix for using wrong leaderboard results & made statistics more robust against slow running remote call --- .../boats/RaceEndWithBoatsPresenterImpl.java | 14 +++++++++++--- ...RaceWithRacemapAndLeaderBoardPresenterImpl.java | 6 +++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/afterliveraceloop/boats/RaceEndWithBoatsPresenterImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/afterliveraceloop/boats/RaceEndWithBoatsPresenterImpl.java index 81c18a839fd..948d037038e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/afterliveraceloop/boats/RaceEndWithBoatsPresenterImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/afterliveraceloop/boats/RaceEndWithBoatsPresenterImpl.java @@ -2,6 +2,7 @@ package com.sap.sailing.gwt.autoplay.client.places.screens.afterliveraceloop.boa import java.util.List; +import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.gwt.user.client.ui.Label; import com.sap.sailing.domain.common.Distance; @@ -95,10 +96,17 @@ public class RaceEndWithBoatsPresenterImpl extends AutoPlayPresenterConfigured lifeRaceResult = leaderboardPanel.getLeaderboard().getRaceList(); + RaceColumnDTO raceColumn = null; + for(RaceColumnDTO column:lifeRaceResult){ + if(column.containsRace(lifeRace)){ + raceColumn = column; + } + } + GWT.debugger(); List sortedCompetitors = leaderboardPanel.getLeaderboard() - .getCompetitorsFromBestToWorst(preselectedRaceColumn); + .getCompetitorsFromBestToWorst(raceColumn); if (sortedCompetitors.size() >= 3) { view.setFirst(sortedCompetitors.get(0)); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java index 01ce293790a..c40061e0b4e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/liveraceloop/racemapwithleaderboard/LiveRaceWithRacemapAndLeaderBoardPresenterImpl.java @@ -119,7 +119,11 @@ public class LiveRaceWithRacemapAndLeaderBoardPresenterImpl List sortedCompetitors = leaderboardPanel.getLeaderboardTable().getVisibleItems(); if (sortedCompetitors.size() > 0) { - view.setStatistic(windSpeed,getPlace().getStatistic().getDistance(), AutoplayHelper.durationOfCurrentLiveRaceRunning()); + if(getPlace().getStatistic() == null){ + view.setStatistic(windSpeed,null, AutoplayHelper.durationOfCurrentLiveRaceRunning()); + }else{ + view.setStatistic(windSpeed,getPlace().getStatistic().getDistance(), AutoplayHelper.durationOfCurrentLiveRaceRunning()); + } } } From 4fe3566e517698d25c1b075c66429af08dea97b9 Mon Sep 17 00:00:00 2001 From: Papick Garcia Taboada Date: Wed, 28 Jun 2017 11:19:12 +0200 Subject: [PATCH 11/13] Introduced method to move listeners from one quickranks provider to another --- .../client/shared/racemap/QuickRanksDTOProvider.java | 10 +++++++++- .../sailing/gwt/ui/client/shared/racemap/RaceMap.java | 7 +++++-- .../ui/raceboard/AbstractQuickRanksDTOProvider.java | 7 +++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/QuickRanksDTOProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/QuickRanksDTOProvider.java index ea9126bd275..a14f05f60fd 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/QuickRanksDTOProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/QuickRanksDTOProvider.java @@ -31,6 +31,13 @@ public interface QuickRanksDTOProvider { void removeQuickRanksListener(QuickRanksListener listener); + /** + * When switching the underlying provider, this method allows to move current listeners to the new provider. + * + * @param newProvider + */ + public void moveListernersTo(QuickRanksDTOProvider newProvider); + /** * The strategy may or may not use this quick ranks information provided directly from the server. This information * may have been provided with some delay and may be slightly inconsistent with a {@link LeaderboardDTO leaderboard} @@ -38,7 +45,8 @@ public interface QuickRanksDTOProvider { * {@link LeaderboardDTO leaderboard} should ignore this call if it already has quick ranks information available * from a leaderboard. * - * @param quickRanksFromServer keys are the competitor IDs as strings + * @param quickRanksFromServer + * keys are the competitor IDs as strings */ void quickRanksReceivedFromServer(Map quickRanksFromServer); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java index da4aa906f4b..5f8e2468ae8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java @@ -487,8 +487,11 @@ public class RaceMap extends AbstractCompositeComponent impleme this.setSize("100%", "100%"); } - public void setQuickRanksDTOProvider(QuickRanksDTOProvider quickRanksDTOProvider) { - this.quickRanksDTOProvider = quickRanksDTOProvider; + public void setQuickRanksDTOProvider(QuickRanksDTOProvider newQuickRanksDTOProvider) { + if (this.quickRanksDTOProvider != null) { + this.quickRanksDTOProvider.moveListernersTo(newQuickRanksDTOProvider); + } + this.quickRanksDTOProvider = newQuickRanksDTOProvider; } /** * The {@link WindDTO#dampenedTrueWindFromDeg} direction if {@link #lastCombinedWindTrackInfoDTO} has a diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/AbstractQuickRanksDTOProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/AbstractQuickRanksDTOProvider.java index 56832763b28..43a10d113c4 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/AbstractQuickRanksDTOProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/AbstractQuickRanksDTOProvider.java @@ -23,6 +23,13 @@ public abstract class AbstractQuickRanksDTOProvider implements QuickRanksDTOProv listeners.remove(listener); } + public void moveListernersTo(QuickRanksDTOProvider newProvider) { + for (QuickRanksListener quickRanksListener : listeners) { + newProvider.addQuickRanksListener(quickRanksListener); + } + listeners.clear(); + } + protected void notifyListeners(String competitorIdAsString, QuickRankDTO oldQuickRank, QuickRankDTO newQuickRank) { for (QuickRanksListener listener : listeners) { listener.rankChanged(competitorIdAsString, oldQuickRank, newQuickRank); From 4df2ba3b1f4a7e46bdc1dfa269bee6a1f6539c6d Mon Sep 17 00:00:00 2001 From: Kai Boernert Date: Wed, 28 Jun 2017 11:37:44 +0200 Subject: [PATCH 12/13] supress race entries, that are wrong for liverace determination, currently races that started more than 24hours ago --- .../autoplay/client/utils/AutoplayHelper.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java index 52027a3ace7..d593a3ef24d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/utils/AutoplayHelper.java @@ -51,15 +51,19 @@ public class AutoplayHelper { private static Timer raceboardTimer = new Timer(PlayModes.Live, /* delayBetweenAutoAdvancesInMilliseconds */1000l); private static Date startOfLifeRace; public static final AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor(); + /** + * If a racestart is longer ago, the race is never considered live, even if all other checks pass + */ + private static final long NEGATIVE_SANITY_CHECK = -24 * 60 * 60 * 1000; - public static long durationOfCurrentLiveRaceRunning(){ - if(startOfLifeRace != null){ - return raceboardTimer.getLiveTimePointInMillis()-startOfLifeRace.getTime(); - }else{ + public static long durationOfCurrentLiveRaceRunning() { + if (startOfLifeRace != null) { + return raceboardTimer.getLiveTimePointInMillis() - startOfLifeRace.getTime(); + } else { return 0; } } - + public static void getLiveRace(SailingServiceAsync sailingService, ErrorReporter errorReporter, EventDTO event, String leaderBoardName, SailingDispatchSystem dispatch, AsyncCallback> callback) { @@ -140,7 +144,7 @@ public class AutoplayHelper { long startTimeInMs = raceTimes.getStartOfRace().getTime(); long delayToLiveInMs = raceTimes.delayToLiveInMs; long startIn = startTimeInMs - serverTimeDuringRequest.getTime() - delayToLiveInMs; - if (startIn <= PRE_RACE_DELAY) { + if (startIn <= PRE_RACE_DELAY && startIn > NEGATIVE_SANITY_CHECK) { startOfLifeRace = raceTimes.getStartOfRace(); return new Pair(startIn, raceIdentifier); } @@ -204,7 +208,7 @@ public class AutoplayHelper { AutoplayHelper.asyncActionsExecutor, errorReporter, raceboardTimer, callback, clientTimeWhenResponseWasReceived, serverTimeDuringRequest, clientTimeWhenRequestWasSent, - raceTimesInfo,new DefaultQuickRanksDTOProvider()); + raceTimesInfo, new DefaultQuickRanksDTOProvider()); } @Override @@ -262,7 +266,8 @@ public class AutoplayHelper { Iterable competitors, SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, ErrorReporter errorReporter, Timer raceboardTimer, AsyncCallback callback, long clientTimeWhenResponseWasReceived, Date serverTimeDuringRequest, - long clientTimeWhenRequestWasSent, Map raceTimesInfos,AbstractQuickRanksDTOProvider provider) { + long clientTimeWhenRequestWasSent, Map raceTimesInfos, + AbstractQuickRanksDTOProvider provider) { ArrayList typesToConsiderOnZoom = new ArrayList<>(); // Other zoom types such as BOATS, TAILS or WINDSENSORS are not currently used as default zoom types. @@ -283,7 +288,7 @@ public class AutoplayHelper { RaceMap raceboardPerspective = new RaceMap(null, null, raceMapLifecycle, settings, sailingService, asyncActionsExecutor, errorReporter, raceboardTimer, competitorSelectionProvider, new RaceCompetitorSet(competitorSelectionProvider), StringMessages.INSTANCE, currentLiveRace, - raceMapResources, false,provider); + raceMapResources, false, provider); raceboardPerspective.raceTimesInfosReceived(raceTimesInfos, clientTimeWhenRequestWasSent, serverTimeDuringRequest, clientTimeWhenResponseWasReceived); // raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceboardPerspective); From d4814ea7a528775eefec8ceafb3d9b7f24bdac1f Mon Sep 17 00:00:00 2001 From: Kai Boernert Date: Wed, 28 Jun 2017 11:38:22 +0200 Subject: [PATCH 13/13] fix for prerace state not showing up reliable --- .../nodes/PreLiveRaceWithRacemapNode.java | 46 ++++++------------- .../racemap/PreRaceRacemapPlace.java | 9 ---- .../racemap/PreRaceRacemapPresenterImpl.java | 4 +- 3 files changed, 15 insertions(+), 44 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/nodes/PreLiveRaceWithRacemapNode.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/nodes/PreLiveRaceWithRacemapNode.java index 989807af537..71dd4dc5019 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/nodes/PreLiveRaceWithRacemapNode.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/nodes/PreLiveRaceWithRacemapNode.java @@ -8,9 +8,6 @@ import com.sap.sailing.gwt.autoplay.client.places.screens.liveraceloop.racemapwi import com.sap.sailing.gwt.autoplay.client.places.screens.preliveraceloop.racemap.PreRaceRacemapPlace; import com.sap.sailing.gwt.autoplay.client.utils.AutoplayHelper; import com.sap.sailing.gwt.autoplay.client.utils.AutoplayHelper.RVWrapper; -import com.sap.sailing.gwt.home.communication.event.minileaderboard.GetMiniLeaderboardDTO; -import com.sap.sailing.gwt.home.communication.event.minileaderboard.GetMiniLeaderbordAction; -import com.sap.sse.gwt.dispatch.shared.commands.ResultWithTTL; public class PreLiveRaceWithRacemapNode extends FiresPlaceNode { private final AutoPlayClientFactory cf; @@ -21,12 +18,12 @@ public class PreLiveRaceWithRacemapNode extends FiresPlaceNode { } - public void onStart() { AutoplayHelper.create(cf.getSailingService(), cf.getErrorReporter(), - cf.getAutoPlayCtx().getContextDefinition().getLeaderboardName(), cf.getAutoPlayCtx().getContextDefinition().getEventId(), - cf.getAutoPlayCtx().getEvent(), cf.getEventBus(), cf.getDispatch(), - cf.getAutoPlayCtx().getPreLiveRace(), new AsyncCallback() { + cf.getAutoPlayCtx().getContextDefinition().getLeaderboardName(), + cf.getAutoPlayCtx().getContextDefinition().getEventId(), cf.getAutoPlayCtx().getEvent(), + cf.getEventBus(), cf.getDispatch(), cf.getAutoPlayCtx().getPreLiveRace(), + new AsyncCallback() { @Override public void onFailure(Throwable caught) { @@ -39,33 +36,16 @@ public class PreLiveRaceWithRacemapNode extends FiresPlaceNode { @Override public void onSuccess(RVWrapper result) { - cf.getDispatch().execute( - new GetMiniLeaderbordAction(cf.getAutoPlayCtx().getEvent().id, - cf.getAutoPlayCtx().getContextDefinition().getLeaderboardName()), - new AsyncCallback>() { - @Override - public void onFailure(Throwable caught) { - // fireEvent(new DataLoadFailureEvent(MiniLeaderboardLoader.this, caught)); - firePlaceChangeAndStartTimer(); - } + PreRaceRacemapPlace place = new PreRaceRacemapPlace(); + place.setRaceMap(result.raceboardPerspective, result.csel); + // add later with settings here + place.setURL(cf.getAutoPlayCtx().getEvent().getOfficialWebsiteURL()); + setPlaceToGo(place); + getBus().fireEvent( + new AutoPlayHeaderEvent(cf.getAutoPlayCtx().getPreLiveRace().getRegattaName(), + cf.getAutoPlayCtx().getPreLiveRace().getRaceName())); + firePlaceChangeAndStartTimer(); - @Override - public void onSuccess(ResultWithTTL resultTTL) { - GetMiniLeaderboardDTO dto = resultTTL.getDto(); - PreRaceRacemapPlace place = new PreRaceRacemapPlace(); - place.setLeaderBoardDTO(dto); - place.setRaceMap(result.raceboardPerspective, result.csel); - // add later with settings here - place.setURL(cf.getAutoPlayCtx().getEvent().getOfficialWebsiteURL()); - setPlaceToGo(place); - getBus().fireEvent( - new AutoPlayHeaderEvent( - cf.getAutoPlayCtx().getPreLiveRace().getRegattaName(), - cf.getAutoPlayCtx().getPreLiveRace().getRaceName())); - firePlaceChangeAndStartTimer(); - - } - }); } }); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPlace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPlace.java index af3f6d34427..7248986e03e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPlace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPlace.java @@ -53,13 +53,4 @@ public class PreRaceRacemapPlace extends Place { public String getUrl() { return url; } - - public void setLeaderBoardDTO(GetMiniLeaderboardDTO dto) { - this.leaderboard = dto; - } - - public GetMiniLeaderboardDTO getLeaderboard() { - return leaderboard; - } - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPresenterImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPresenterImpl.java index 8b2939ba4d0..d58598e7a4a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPresenterImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/places/screens/preliveraceloop/racemap/PreRaceRacemapPresenterImpl.java @@ -77,7 +77,7 @@ public class PreRaceRacemapPresenterImpl extends AutoPlayPresenterConfigured
() {