mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
Merge remote-tracking branch 'origin/master' into 60_inch
# Conflicts: # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java # java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
This commit is contained in:
commit
07f36ed3ae
27 files changed
+266
-113
No files matched your search
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+9
-28
@@ -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("</html>");
|
||||
|
||||
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", "<image>");
|
||||
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 {
|
||||
|
||||
-11
@@ -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;
|
||||
@@ -53,14 +52,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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-2
@@ -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"));
|
||||
|
||||
+2
-4
@@ -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);
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
+15
-13
@@ -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<Void>(
|
||||
new AsyncCallback<Void>() {
|
||||
@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<Void>(new AsyncCallback<Void>() {
|
||||
@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();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -1817,6 +1817,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String showRacePlaceColumn();
|
||||
String unknownLeaderboardType(String name);
|
||||
String selectCompetitorsToEliminate();
|
||||
String trackedRaceAlreadyLinked();
|
||||
String trackedRaceAlreadyLinked();
|
||||
String reallyRemoveSeries(String seriesName);
|
||||
String noData();
|
||||
}
|
||||
+1
@@ -1796,4 +1796,5 @@ showRacePlaceColumn=Show race place
|
||||
estimatedDistance=Estimated Distance
|
||||
estimatedTime=Estimated Time
|
||||
nothingUpcoming=There are currently no further planned races
|
||||
reallyRemoveSeries=Do you really want to remove the series ''{0}''? Note: all race logs for the attached race columns will also permanently be removed!
|
||||
noData=No data is available
|
||||
+2
-1
@@ -1775,4 +1775,5 @@ raceRankShort=Platz
|
||||
showRacePlaceColumn=Rennplazierungsspalte
|
||||
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?
|
||||
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!
|
||||
+7
-6
@@ -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<String, QuickRankDTO> quickRanksFromServer;
|
||||
private Map<String, QuickRankDTO> currentQuickRanksFromServer = Collections.emptyMap();
|
||||
|
||||
@Override
|
||||
public void quickRanksReceivedFromServer(Map<String, QuickRankDTO> quickRanksFromServer) {
|
||||
final Map<String, QuickRankDTO> oldQuickRanksFromServer = quickRanksFromServer;
|
||||
this.quickRanksFromServer = quickRanksFromServer;
|
||||
for (final Entry<String, QuickRankDTO> e : quickRanksFromServer.entrySet()) {
|
||||
public void quickRanksReceivedFromServer(Map<String, QuickRankDTO> receivedQuickRanksFromServer) {
|
||||
final Map<String, QuickRankDTO> oldQuickRanksFromServer = this.currentQuickRanksFromServer;
|
||||
this.currentQuickRanksFromServer = Util.nullToEmptyMap(receivedQuickRanksFromServer);
|
||||
for (final Entry<String, QuickRankDTO> 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<String, QuickRankDTO> getQuickRanks() {
|
||||
return quickRanksFromServer;
|
||||
return currentQuickRanksFromServer;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -1406,7 +1406,8 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> 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<CompetitorDTO> 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
|
||||
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -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;
|
||||
|
||||
+8
-23
@@ -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<T> 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);
|
||||
|
||||
@@ -514,7 +514,7 @@ public class Util {
|
||||
* {@link #isEmpty(Iterable) isEmpty(splitAlongWhitespaceRespectingDoubleQuotedPhrases(" \n\t "))
|
||||
* </pre>
|
||||
*
|
||||
* @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<String> splitAlongWhitespaceRespectingDoubleQuotedPhrases(String s) {
|
||||
@@ -734,4 +734,14 @@ public class Util {
|
||||
public static <T extends Comparable<T>> 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 <K, V> Map<K, V> nullToEmptyMap(Map<K, V> map) {
|
||||
if (map == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -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, ContentSetter contentSetter)
|
||||
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];
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.sap.sse.mail;
|
||||
|
||||
import javax.mail.Multipart;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.mail.MailException;
|
||||
@@ -29,5 +31,5 @@ public interface MailService extends ReplicableWithObjectInputStream<ReplicableM
|
||||
/**
|
||||
* Send mail with multipart content (e.g. inline image).
|
||||
*/
|
||||
void sendMail(String toAddress, String subject, Multipart multipartContent) throws MailException;
|
||||
void sendMail(String toAddress, String subject, SerializableMultipartSupplier multipartContent) throws MailException, IOException, MessagingException;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.sap.sse.mail;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.activation.DataSource;
|
||||
import javax.mail.internet.MimeBodyPart;
|
||||
import javax.mail.util.ByteArrayDataSource;
|
||||
|
||||
import com.sap.sse.qrcode.QRCodeGenerationUtil;
|
||||
|
||||
/**
|
||||
* Constructs a MIME body part containing a QR code for a {@link #text} provided to this object
|
||||
* at construction time.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class QRCodeMimeBodyPartSupplier implements SerializableMimeBodyPartSupplier {
|
||||
private static final long serialVersionUID = 6073707813859319317L;
|
||||
private final String text;
|
||||
|
||||
public QRCodeMimeBodyPartSupplier(String text) {
|
||||
super();
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MimeBodyPart get() {
|
||||
final MimeBodyPart messageImagePart = new MimeBodyPart();
|
||||
InputStream imageIs;
|
||||
try {
|
||||
imageIs = QRCodeGenerationUtil.create(text, 250);
|
||||
final DataSource imageDs = new ByteArrayDataSource(imageIs, "image/png");
|
||||
messageImagePart.setDataHandler(new DataHandler(imageDs));
|
||||
messageImagePart.setHeader("Content-ID", "<image>");
|
||||
messageImagePart.setHeader("Content-Disposition", "inline;filename=\"qr.png\"");
|
||||
return messageImagePart;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+36
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -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<MimeBodyPart>, Serializable {
|
||||
}
|
||||
+33
@@ -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<Multipart>, 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;
|
||||
}
|
||||
}
|
||||
@@ -17,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;
|
||||
@@ -28,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;
|
||||
@@ -68,7 +68,7 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
protected static interface ContentSetter {
|
||||
void setContent(MimeMessage msg) throws MessagingException;
|
||||
}
|
||||
|
||||
|
||||
private boolean canSendMail() {
|
||||
return mailProperties != null && mailProperties.containsKey("mail.transport.protocol");
|
||||
}
|
||||
@@ -88,16 +88,12 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
msg.setSubject(subject);
|
||||
}
|
||||
msg.addRecipient(RecipientType.TO, new InternetAddress(toAddress.trim()));
|
||||
|
||||
// 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();
|
||||
ts.connect();
|
||||
ts.sendMessage(msg, msg.getRecipients(RecipientType.TO));
|
||||
@@ -134,19 +130,19 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void internalSendMail(String toAddress, String subject, Multipart multipartContent) throws MailException {
|
||||
public Void internalSendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException {
|
||||
internalSendMail(toAddress, subject, new ContentSetter() {
|
||||
@Override
|
||||
public void setContent(MimeMessage msg) throws MessagingException {
|
||||
msg.setContent(multipartContent);
|
||||
msg.setContent(multipartSupplier.get());
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMail(String toAddress, String subject, Multipart multipartContent) throws MailException {
|
||||
apply(s -> s.internalSendMail(toAddress, subject, multipartContent));
|
||||
public void sendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException {
|
||||
apply(s -> s.internalSendMail(toAddress, subject, multipartSupplier));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package com.sap.sse.mail.impl;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Multipart;
|
||||
|
||||
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;
|
||||
Void internalSendMail(String toAddress, String subject, String body) throws MailException, MessagingException;
|
||||
|
||||
Void internalSendMail(String toAddress, String subject, Multipart multipartContent) throws MailException;
|
||||
/**
|
||||
* @param multipartSupplier
|
||||
* can produce a {@link Multipart} object and must be serializable
|
||||
*/
|
||||
Void internalSendMail(String toAddress, String subject, SerializableMultipartSupplier multipartSupplier) throws MailException, MessagingException;
|
||||
}
|
||||
@@ -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<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType,
|
||||
ErrorCorrectionLevel>();
|
||||
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
|
||||
|
||||
Reference in new issue
Block a user