Bug 4371: Split of WindImporter and WindImportServlet as preparation to

reuse it in the context of expedition all in one import
This commit is contained in:
Steffen Schaefer committed 2017-12-18 16:33:46 +01:00
1 parent 34533623f0
commit b077f455bc
10 files changed
+470 -399

No files matched your search

@@ -1,12 +1,7 @@
package com.sap.sailing.server.gateway.windimport;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -24,127 +19,19 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.server.gateway.SailingServerHttpServlet;
import com.sap.sailing.server.gateway.windimport.AbstractWindImportServlet.WindImportResult.RaceEntry;
import com.sap.sse.common.Util;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter.UploadRequest;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter.WindImportResult;
public abstract class AbstractWindImportServlet extends SailingServerHttpServlet {
private static final Logger logger = Logger.getLogger(AbstractWindImportServlet.class.getName());
private static final long serialVersionUID = 1L;
public static class UploadRequest {
public String boatId;
public final List<FileItem> files = new ArrayList<FileItem>();
public List<RegattaAndRaceIdentifier> races = new ArrayList<RegattaAndRaceIdentifier>();;
}
static class WindImportResult {
private Date first;
private Date last;
public String error;
public final List<RaceEntry> raceEntries = new ArrayList<RaceEntry>();
public Date getFirst() {
return first;
}
public Date getLast() {
return last;
}
public void update(Wind newWind) {
Date newDate = newWind.getTimePoint().asDate();
if (this.first == null || newDate.before(this.first)) {
this.first = newDate;
}
if (this.last == null || newDate.after(this.last)) {
this.last = newDate;
}
}
RaceEntry addRaceEntry(String regattaName, String raceName) {
RaceEntry raceEntry = new RaceEntry(regattaName, raceName);
raceEntries.add(raceEntry);
return raceEntry;
}
static class RaceEntry {
public final String regattaName;
public final String raceName;
private int count;
private Date first;
private Date last;
private RaceEntry(String regattaName, String raceName) {
this.regattaName = regattaName;
this.raceName = raceName;
}
public void update(Wind newWind) {
count++;
Date newDate = newWind.getTimePoint().asDate();
if (this.first == null || newDate.before(this.first)) {
this.first = newDate;
}
if (this.last == null || newDate.after(this.last)) {
this.last = newDate;
}
}
public int getCount() {
return count;
}
public Date getFirst() {
return first;
}
public Date getLast() {
return last;
}
private JSONObject json() {
JSONObject result = new JSONObject();
result.put("regattaName", regattaName);
result.put("raceName", raceName);
result.put("count", getCount());
if (getFirst() != null) {
result.put("first", getFirst().getTime());
}
if (getLast() != null) {
result.put("last", getLast().getTime());
}
return result;
}
}
public JSONObject json() {
JSONObject result = new JSONObject();
if (getFirst() != null) {
result.put("first", getFirst().getTime());
}
if (getLast() != null) {
result.put("last", getLast().getTime());
}
result.put("error", error);
JSONArray raceEntriesJson = new JSONArray();
for (RaceEntry raceEntry : raceEntries) {
if (raceEntry.count > 0) {
raceEntriesJson.add(raceEntry.json());
}
}
result.put("raceEntries", raceEntriesJson);
return result;
}
private final AbstractWindImporter importer;
public AbstractWindImportServlet(AbstractWindImporter importer) {
this.importer = importer;
}
@Override
@@ -157,41 +44,7 @@ public abstract class AbstractWindImportServlet extends SailingServerHttpServlet
WindImportResult windImportResult = new WindImportResult();
try {
UploadRequest uploadRequest = readRequest(request);
WindSource windSource = getWindSource(uploadRequest);
List<DynamicTrackedRace> trackedRaces = new ArrayList<DynamicTrackedRace>();
if (uploadRequest.races.size() > 0) {
for (RegattaAndRaceIdentifier raceEntry : uploadRequest.races) {
DynamicTrackedRace trackedRace = getService().getTrackedRace(raceEntry);
if (trackedRace != null) {
trackedRaces.add(trackedRace);
}
}
} else {
for (Regatta regatta : getService().getAllRegattas()) {
for (RaceDefinition raceDefinition : regatta.getAllRaces()) {
trackedRaces.add(getService().getTrackedRegatta(regatta).getTrackedRace(raceDefinition));
}
}
}
final Map<InputStream, String> streamsWithFilenames = new HashMap<>();
for (FileItem file : uploadRequest.files) {
streamsWithFilenames.put(file.getInputStream(), file.getName());
}
Iterable<Wind> windFixes = importWind(streamsWithFilenames);
if (!Util.isEmpty(windFixes)) {
for (DynamicTrackedRace trackedRace : trackedRaces) {
RegattaAndRaceIdentifier raceIdentifier = trackedRace.getRaceIdentifier();
RaceEntry raceEntry = windImportResult.addRaceEntry(raceIdentifier.getRegattaName(),
raceIdentifier.getRaceName());
for (Wind wind : windFixes) {
windImportResult.update(wind);
if (trackedRace.recordWind(wind, windSource)) {
raceEntry.update(wind);
}
}
getService().getPolarDataService().insertExistingFixes(trackedRace);
}
}
importer.importWindForUploadRequest(getService(), windImportResult, uploadRequest);
// Use text/html to prevent browsers from wrapping the response body,
// see "Handling File Upload Responses in GWT" at http://www.artofsolving.com/node/50
} catch (Exception e) {
@@ -202,11 +55,6 @@ public abstract class AbstractWindImportServlet extends SailingServerHttpServlet
response.getWriter().append(windImportResult.json().toJSONString());
}
protected abstract Iterable<Wind> importWind(Map<InputStream, String> streamsWithFilenames)
throws IOException, InterruptedException, FormatNotSupportedException;
protected abstract WindSource getWindSource(UploadRequest uploadRequest);
private UploadRequest readRequest(HttpServletRequest req) throws FileUploadException, ParseException {
UploadRequest result = new UploadRequest();
// http://commons.apache.org/fileupload/using.html
@@ -0,0 +1,183 @@
package com.sap.sailing.server.gateway.windimport;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.fileupload.FileItem;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter.WindImportResult.RaceEntry;
import com.sap.sse.common.Util;
public abstract class AbstractWindImporter {
public static class UploadRequest {
public String boatId;
public final List<FileItem> files = new ArrayList<FileItem>();
public List<RegattaAndRaceIdentifier> races = new ArrayList<RegattaAndRaceIdentifier>();;
}
public static class WindImportResult {
private Date first;
private Date last;
public String error;
public final List<RaceEntry> raceEntries = new ArrayList<RaceEntry>();
public Date getFirst() {
return first;
}
public Date getLast() {
return last;
}
public void update(Wind newWind) {
Date newDate = newWind.getTimePoint().asDate();
if (this.first == null || newDate.before(this.first)) {
this.first = newDate;
}
if (this.last == null || newDate.after(this.last)) {
this.last = newDate;
}
}
RaceEntry addRaceEntry(String regattaName, String raceName) {
RaceEntry raceEntry = new RaceEntry(regattaName, raceName);
raceEntries.add(raceEntry);
return raceEntry;
}
static class RaceEntry {
public final String regattaName;
public final String raceName;
private int count;
private Date first;
private Date last;
private RaceEntry(String regattaName, String raceName) {
this.regattaName = regattaName;
this.raceName = raceName;
}
public void update(Wind newWind) {
count++;
Date newDate = newWind.getTimePoint().asDate();
if (this.first == null || newDate.before(this.first)) {
this.first = newDate;
}
if (this.last == null || newDate.after(this.last)) {
this.last = newDate;
}
}
public int getCount() {
return count;
}
public Date getFirst() {
return first;
}
public Date getLast() {
return last;
}
private JSONObject json() {
JSONObject result = new JSONObject();
result.put("regattaName", regattaName);
result.put("raceName", raceName);
result.put("count", getCount());
if (getFirst() != null) {
result.put("first", getFirst().getTime());
}
if (getLast() != null) {
result.put("last", getLast().getTime());
}
return result;
}
}
public JSONObject json() {
JSONObject result = new JSONObject();
if (getFirst() != null) {
result.put("first", getFirst().getTime());
}
if (getLast() != null) {
result.put("last", getLast().getTime());
}
result.put("error", error);
JSONArray raceEntriesJson = new JSONArray();
for (RaceEntry raceEntry : raceEntries) {
if (raceEntry.count > 0) {
raceEntriesJson.add(raceEntry.json());
}
}
result.put("raceEntries", raceEntriesJson);
return result;
}
}
public void importWindForUploadRequest(RacingEventService service, WindImportResult windImportResult, UploadRequest uploadRequest)
throws IOException, InterruptedException, FormatNotSupportedException {
WindSource windSource = getWindSource(uploadRequest);
List<DynamicTrackedRace> trackedRaces = new ArrayList<DynamicTrackedRace>();
if (uploadRequest.races.size() > 0) {
for (RegattaAndRaceIdentifier raceEntry : uploadRequest.races) {
DynamicTrackedRace trackedRace = service.getTrackedRace(raceEntry);
if (trackedRace != null) {
trackedRaces.add(trackedRace);
}
}
} else {
for (Regatta regatta : service.getAllRegattas()) {
for (RaceDefinition raceDefinition : regatta.getAllRaces()) {
trackedRaces.add(service.getTrackedRegatta(regatta).getTrackedRace(raceDefinition));
}
}
}
final Map<InputStream, String> streamsWithFilenames = new HashMap<>();
for (FileItem file : uploadRequest.files) {
streamsWithFilenames.put(file.getInputStream(), file.getName());
}
importWindToWindSourceAndTrackedRaces(service, windImportResult, windSource, trackedRaces, streamsWithFilenames);
}
public void importWindToWindSourceAndTrackedRaces(RacingEventService service, WindImportResult windImportResult, WindSource windSource,
List<DynamicTrackedRace> trackedRaces, final Map<InputStream, String> streamsWithFilenames)
throws IOException, InterruptedException, FormatNotSupportedException {
Iterable<Wind> windFixes = importWind(streamsWithFilenames);
if (!Util.isEmpty(windFixes)) {
for (DynamicTrackedRace trackedRace : trackedRaces) {
RegattaAndRaceIdentifier raceIdentifier = trackedRace.getRaceIdentifier();
RaceEntry raceEntry = windImportResult.addRaceEntry(raceIdentifier.getRegattaName(),
raceIdentifier.getRaceName());
for (Wind wind : windFixes) {
windImportResult.update(wind);
if (trackedRace.recordWind(wind, windSource)) {
raceEntry.update(wind);
}
}
service.getPolarDataService().insertExistingFixes(trackedRace);
}
}
}
protected abstract Iterable<Wind> importWind(Map<InputStream, String> streamsWithFilenames)
throws IOException, InterruptedException, FormatNotSupportedException;
protected abstract WindSource getWindSource(UploadRequest uploadRequest);
}
@@ -1,119 +1,11 @@
package com.sap.sailing.server.gateway.windimport.bravo;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.WindImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier;
import com.sap.sailing.domain.trackimport.BaseDoubleVectorFixImporter.Callback;
import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.server.gateway.windimport.AbstractWindImportServlet;
import com.sap.sailing.server.trackfiles.impl.BaseBravoDataImporterImpl;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class BravoWindImportServlet extends AbstractWindImportServlet {
private static final String BRAVO_WIND_IMPORT = "Bravo Wind Import";
private static final String GZIP_SUFFIX = ".gz";
private static final long serialVersionUID = -4547876638456305135L;
private static final Logger logger = Logger.getLogger(BravoWindImportServlet.class.getName());
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
final WindSource windSource;
final String sourceName;
logger.info("Importing Bravo wind data from "+uploadRequest.files);
if (uploadRequest.files != null && !uploadRequest.files.isEmpty()) {
sourceName = uploadRequest.files.stream().map(f->f.getName()).collect(Collectors.joining(", "));
} else {
sourceName = BRAVO_WIND_IMPORT;
}
windSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, sourceName + "@" + MillisecondsTimePoint.now());
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> inputStreamsAndFilenames) throws IOException, InterruptedException, FormatNotSupportedException {
final Iterable<Wind> result;
if (inputStreamsAndFilenames != null && inputStreamsAndFilenames.size() == 1) {
logger.info("Reading Bravo wind data from "+inputStreamsAndFilenames.values().iterator().next());
result = readWind(inputStreamsAndFilenames.values().iterator().next(), inputStreamsAndFilenames.keySet().iterator().next());
} else {
final List<Wind> windList = new LinkedList<>();
for (final Entry<InputStream, String> inputStreamAndFileName : inputStreamsAndFilenames.entrySet()) {
logger.info("Reading Bravo wind data from "+inputStreamAndFileName.getValue());
Util.addAll(readWind(inputStreamAndFileName.getValue(), inputStreamAndFileName.getKey()), windList);
}
result = windList;
}
return result;
}
private static enum Fields {
Lat, Lon, TWS, TWD;
}
private Iterable<Wind> readWind(String filename, InputStream inputStream) throws InterruptedException, IOException, FormatNotSupportedException {
final List<Wind> result = new LinkedList<>();
Map<String, Integer> columnsMap = new HashMap<>();
for (final Fields field : Fields.values()) {
columnsMap.put(field.name(), field.ordinal());
}
final BaseBravoDataImporterImpl importer = new BaseBravoDataImporterImpl(columnsMap, BRAVO_WIND_IMPORT);
final Callback callback = new Callback() {
@Override
public void addFixes(Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier device) {
for (final DoubleVectorFix fix : fixes) {
// latitude / longitude are represented in funny NMEA-like way; the value divided by 100 as
// a floored integer represents the full degrees; the value modulo 100 represents the decimal
// minutes. Example: the pair (4124.645890, 213.738670) stands for N41�24.645890 E002�13.738670
final Wind wind = new WindImpl(new DegreePosition(FunnyDegreeConverter.funnyLatLng(fix.get(Fields.Lat.ordinal())),
FunnyDegreeConverter.funnyLatLng(fix.get(Fields.Lon.ordinal()))),
fix.getTimePoint(), new KnotSpeedWithBearingImpl(fix.get(Fields.TWS.ordinal()),
new DegreeBearingImpl(fix.get(Fields.TWD.ordinal())).reverse()));
result.add(wind);
}
}
};
if (filename.toLowerCase().endsWith(".zip")) {
logger.info("Bravo file "+filename+" is a ZIP file");
try (final ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry entry;
while ((entry=zipInputStream.getNextEntry()) != null) {
if (entry.getName().toLowerCase().endsWith(".txt")) {
logger.info("Reading Bravo wind data from "+filename+"'s ZIP entry "+entry.getName());
importer.importFixes(zipInputStream, callback, entry.getName(), BRAVO_WIND_IMPORT, /* downsample */ false);
}
}
}
} else {
final String actualFileName;
if (filename.toLowerCase().endsWith(GZIP_SUFFIX)) {
inputStream = new GZIPInputStream(inputStream);
actualFileName = filename.substring(0, filename.length()-GZIP_SUFFIX.length());
} else {
actualFileName = filename;
}
importer.importFixes(inputStream, callback, actualFileName, BRAVO_WIND_IMPORT, /* downsample */ false);
}
return result;
public BravoWindImportServlet() {
super(new BravoWindImporter());
}
}
@@ -0,0 +1,118 @@
package com.sap.sailing.server.gateway.windimport.bravo;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.WindImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier;
import com.sap.sailing.domain.trackimport.BaseDoubleVectorFixImporter.Callback;
import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sailing.server.trackfiles.impl.BaseBravoDataImporterImpl;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class BravoWindImporter extends AbstractWindImporter {
private static final String BRAVO_WIND_IMPORT = "Bravo Wind Import";
private static final String GZIP_SUFFIX = ".gz";
private static final Logger logger = Logger.getLogger(BravoWindImporter.class.getName());
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
final WindSource windSource;
final String sourceName;
logger.info("Importing Bravo wind data from "+uploadRequest.files);
if (uploadRequest.files != null && !uploadRequest.files.isEmpty()) {
sourceName = uploadRequest.files.stream().map(f->f.getName()).collect(Collectors.joining(", "));
} else {
sourceName = BRAVO_WIND_IMPORT;
}
windSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, sourceName + "@" + MillisecondsTimePoint.now());
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> inputStreamsAndFilenames) throws IOException, InterruptedException, FormatNotSupportedException {
final Iterable<Wind> result;
if (inputStreamsAndFilenames != null && inputStreamsAndFilenames.size() == 1) {
logger.info("Reading Bravo wind data from "+inputStreamsAndFilenames.values().iterator().next());
result = readWind(inputStreamsAndFilenames.values().iterator().next(), inputStreamsAndFilenames.keySet().iterator().next());
} else {
final List<Wind> windList = new LinkedList<>();
for (final Entry<InputStream, String> inputStreamAndFileName : inputStreamsAndFilenames.entrySet()) {
logger.info("Reading Bravo wind data from "+inputStreamAndFileName.getValue());
Util.addAll(readWind(inputStreamAndFileName.getValue(), inputStreamAndFileName.getKey()), windList);
}
result = windList;
}
return result;
}
private static enum Fields {
Lat, Lon, TWS, TWD;
}
private Iterable<Wind> readWind(String filename, InputStream inputStream) throws InterruptedException, IOException, FormatNotSupportedException {
final List<Wind> result = new LinkedList<>();
Map<String, Integer> columnsMap = new HashMap<>();
for (final Fields field : Fields.values()) {
columnsMap.put(field.name(), field.ordinal());
}
final BaseBravoDataImporterImpl importer = new BaseBravoDataImporterImpl(columnsMap, BRAVO_WIND_IMPORT);
final Callback callback = new Callback() {
@Override
public void addFixes(Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier device) {
for (final DoubleVectorFix fix : fixes) {
// latitude / longitude are represented in funny NMEA-like way; the value divided by 100 as
// a floored integer represents the full degrees; the value modulo 100 represents the decimal
// minutes. Example: the pair (4124.645890, 213.738670) stands for N41�24.645890 E002�13.738670
final Wind wind = new WindImpl(new DegreePosition(FunnyDegreeConverter.funnyLatLng(fix.get(Fields.Lat.ordinal())),
FunnyDegreeConverter.funnyLatLng(fix.get(Fields.Lon.ordinal()))),
fix.getTimePoint(), new KnotSpeedWithBearingImpl(fix.get(Fields.TWS.ordinal()),
new DegreeBearingImpl(fix.get(Fields.TWD.ordinal())).reverse()));
result.add(wind);
}
}
};
if (filename.toLowerCase().endsWith(".zip")) {
logger.info("Bravo file "+filename+" is a ZIP file");
try (final ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
ZipEntry entry;
while ((entry=zipInputStream.getNextEntry()) != null) {
if (entry.getName().toLowerCase().endsWith(".txt")) {
logger.info("Reading Bravo wind data from "+filename+"'s ZIP entry "+entry.getName());
importer.importFixes(zipInputStream, callback, entry.getName(), BRAVO_WIND_IMPORT, /* downsample */ false);
}
}
}
} else {
final String actualFileName;
if (filename.toLowerCase().endsWith(GZIP_SUFFIX)) {
inputStream = new GZIPInputStream(inputStream);
actualFileName = filename.substring(0, filename.length()-GZIP_SUFFIX.length());
} else {
actualFileName = filename;
}
importer.importFixes(inputStream, callback, actualFileName, BRAVO_WIND_IMPORT, /* downsample */ false);
}
return result;
}
}
@@ -1,40 +1,12 @@
package com.sap.sailing.server.gateway.windimport.expedition;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.server.gateway.windimport.AbstractWindImportServlet;
import com.sap.sse.common.Util;
public class WindImportServlet extends AbstractWindImportServlet {
private static final long serialVersionUID = 1L;
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
WindSource windSource;
if (uploadRequest.boatId == null) {
windSource = new WindSourceImpl(WindSourceType.EXPEDITION);
} else {
windSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, uploadRequest.boatId);
}
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> streamsWithFilenames) throws IOException {
final List<Wind> result = new ArrayList<>();
for (final InputStream inputStream : streamsWithFilenames.keySet()) {
Util.addAll(WindLogParser.importWind(inputStream), result);
}
return result;
public WindImportServlet() {
super(new WindImporter());
}
}
@@ -0,0 +1,38 @@
package com.sap.sailing.server.gateway.windimport.expedition;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sse.common.Util;
public class WindImporter extends AbstractWindImporter {
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
WindSource windSource;
if (uploadRequest.boatId == null) {
windSource = new WindSourceImpl(WindSourceType.EXPEDITION);
} else {
windSource = new WindSourceWithAdditionalID(WindSourceType.EXPEDITION, uploadRequest.boatId);
}
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> streamsWithFilenames) throws IOException {
final List<Wind> result = new ArrayList<>();
for (final InputStream inputStream : streamsWithFilenames.keySet()) {
Util.addAll(WindLogParser.importWind(inputStream), result);
}
return result;
}
}
@@ -1,38 +1,11 @@
package com.sap.sailing.server.gateway.windimport.grib;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.grib.GribWindField;
import com.sap.sailing.grib.GribWindFieldFactory;
import com.sap.sailing.server.gateway.windimport.AbstractWindImportServlet;
public class GribWindImportServlet extends AbstractWindImportServlet {
private static final long serialVersionUID = -4547876638456305135L;
private static final Logger logger = Logger.getLogger(GribWindImportServlet.class.getName());
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
WindSource windSource;
if (uploadRequest.boatId == null) {
windSource = new WindSourceImpl(WindSourceType.WEB);
} else {
windSource = new WindSourceWithAdditionalID(WindSourceType.WEB, uploadRequest.boatId);
}
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> inputStreamsAndFilenames) throws IOException {
final GribWindField windField = GribWindFieldFactory.INSTANCE.createGribWindFieldFromStreams(logger, Level.INFO, inputStreamsAndFilenames);
return windField.getAllWindFixes();
public GribWindImportServlet() {
super(new GribWindImporter());
}
}
@@ -0,0 +1,37 @@
package com.sap.sailing.server.gateway.windimport.grib;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.grib.GribWindField;
import com.sap.sailing.grib.GribWindFieldFactory;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
public class GribWindImporter extends AbstractWindImporter {
private static final Logger logger = Logger.getLogger(GribWindImporter.class.getName());
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
WindSource windSource;
if (uploadRequest.boatId == null) {
windSource = new WindSourceImpl(WindSourceType.WEB);
} else {
windSource = new WindSourceWithAdditionalID(WindSourceType.WEB, uploadRequest.boatId);
}
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> inputStreamsAndFilenames) throws IOException {
final GribWindField windField = GribWindFieldFactory.INSTANCE.createGribWindFieldFromStreams(logger, Level.INFO, inputStreamsAndFilenames);
return windField.getAllWindFixes();
}
}
@@ -1,76 +1,11 @@
package com.sap.sailing.server.gateway.windimport.nmea;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.nmeaconnector.NmeaFactory;
import com.sap.sailing.server.gateway.windimport.AbstractWindImportServlet;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class NmeaWindImportServlet extends AbstractWindImportServlet {
private static final long serialVersionUID = -4547876638456305135L;
private static final Logger logger = Logger.getLogger(NmeaWindImportServlet.class.getName());
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
final WindSource windSource;
final String sourceName;
logger.info("Importing NMEA wind data from "+uploadRequest.files);
if (uploadRequest.files != null && !uploadRequest.files.isEmpty()) {
sourceName = uploadRequest.files.toString();
} else {
sourceName = "NMEA Wind Import";
}
windSource = new WindSourceWithAdditionalID(WindSourceType.WEB, sourceName + "@" + MillisecondsTimePoint.now());
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> inputStreamsAndFilenames) throws IOException, InterruptedException {
final Iterable<Wind> result;
if (inputStreamsAndFilenames != null && inputStreamsAndFilenames.size() == 1) {
logger.info("Reading NMEA wind data from "+inputStreamsAndFilenames.values().iterator().next());
result = readWind(inputStreamsAndFilenames.values().iterator().next(), inputStreamsAndFilenames.keySet().iterator().next());
} else {
final List<Wind> windList = new LinkedList<>();
for (final Entry<InputStream, String> inputStreamAndFileName : inputStreamsAndFilenames.entrySet()) {
logger.info("Reading NMEA wind data from "+inputStreamAndFileName.getValue());
Util.addAll(readWind(inputStreamAndFileName.getValue(), inputStreamAndFileName.getKey()), windList);
}
result = windList;
}
return result;
}
private Iterable<Wind> readWind(String filename, InputStream inputStream) throws InterruptedException, IOException {
final Iterable<Wind> result;
if (filename.toLowerCase().endsWith("zip")) {
logger.info("NMEA file "+filename+" is a ZIP file");
final List<Wind> windList = new LinkedList<>();
final ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry entry;
while ((entry=zipInputStream.getNextEntry()) != null) {
if (entry.getName().toLowerCase().endsWith(".txt")) {
logger.info("Reading NMEA wind data from "+filename+"'s ZIP entry "+entry.getName());
Util.addAll(NmeaFactory.INSTANCE.readWind(zipInputStream), windList);
}
}
result = windList;
} else {
result = NmeaFactory.INSTANCE.readWind(inputStream);
}
return result;
public NmeaWindImportServlet() {
super(new NmeaWindImporter());
}
}
@@ -0,0 +1,75 @@
package com.sap.sailing.server.gateway.windimport.nmea;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
import com.sap.sailing.nmeaconnector.NmeaFactory;
import com.sap.sailing.server.gateway.windimport.AbstractWindImporter;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class NmeaWindImporter extends AbstractWindImporter {
private static final Logger logger = Logger.getLogger(NmeaWindImporter.class.getName());
@Override
protected WindSource getWindSource(UploadRequest uploadRequest) {
final WindSource windSource;
final String sourceName;
logger.info("Importing NMEA wind data from "+uploadRequest.files);
if (uploadRequest.files != null && !uploadRequest.files.isEmpty()) {
sourceName = uploadRequest.files.toString();
} else {
sourceName = "NMEA Wind Import";
}
windSource = new WindSourceWithAdditionalID(WindSourceType.WEB, sourceName + "@" + MillisecondsTimePoint.now());
return windSource;
}
@Override
protected Iterable<Wind> importWind(Map<InputStream, String> inputStreamsAndFilenames) throws IOException, InterruptedException {
final Iterable<Wind> result;
if (inputStreamsAndFilenames != null && inputStreamsAndFilenames.size() == 1) {
logger.info("Reading NMEA wind data from "+inputStreamsAndFilenames.values().iterator().next());
result = readWind(inputStreamsAndFilenames.values().iterator().next(), inputStreamsAndFilenames.keySet().iterator().next());
} else {
final List<Wind> windList = new LinkedList<>();
for (final Entry<InputStream, String> inputStreamAndFileName : inputStreamsAndFilenames.entrySet()) {
logger.info("Reading NMEA wind data from "+inputStreamAndFileName.getValue());
Util.addAll(readWind(inputStreamAndFileName.getValue(), inputStreamAndFileName.getKey()), windList);
}
result = windList;
}
return result;
}
private Iterable<Wind> readWind(String filename, InputStream inputStream) throws InterruptedException, IOException {
final Iterable<Wind> result;
if (filename.toLowerCase().endsWith("zip")) {
logger.info("NMEA file "+filename+" is a ZIP file");
final List<Wind> windList = new LinkedList<>();
final ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ZipEntry entry;
while ((entry=zipInputStream.getNextEntry()) != null) {
if (entry.getName().toLowerCase().endsWith(".txt")) {
logger.info("Reading NMEA wind data from "+filename+"'s ZIP entry "+entry.getName());
Util.addAll(NmeaFactory.INSTANCE.readWind(zipInputStream), windList);
}
}
result = windList;
} else {
result = NmeaFactory.INSTANCE.readWind(inputStream);
}
return result;
}
}