mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-14 22:43:57 +00:00
fixed stream handling during wind import; close outside of importFixes to allow for ZIP files
Change-Id: I84ad6234ff51e3738c70df0f48e41d6a4fd73881
This commit is contained in:
1 parent
47d479195f
commit
9e367f958e
4 files changed
+73
-66
No files matched your search
+7
-6
@@ -93,12 +93,13 @@ public class BravoWindImportServlet extends AbstractWindImportServlet {
|
||||
};
|
||||
if (filename.toLowerCase().endsWith("zip")) {
|
||||
logger.info("Bravo file "+filename+" is a ZIP file");
|
||||
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, filename, filename, /* downsample */ false);
|
||||
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, filename, filename, /* downsample */ false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
+11
-9
@@ -51,15 +51,17 @@ public abstract class AbstractBravoDataImportTest {
|
||||
}
|
||||
|
||||
protected void testImport(ImportDataDefinition importData) throws FormatNotSupportedException, IOException {
|
||||
bravoDataImporter.importFixes(importData.getInputStream(), (fixes, device) -> {
|
||||
for (DoubleVectorFix fix : fixes) {
|
||||
callbackCallCount++;
|
||||
sumRideHeightInMeters += new BravoFixImpl(fix).getRideHeight().getMeters();
|
||||
}
|
||||
}, "filename", "source", /* downsample */ true);
|
||||
Assert.assertEquals(importData.getExpectedFixesCount(), downsampler.getCountSourceTtl());
|
||||
Assert.assertEquals(importData.getExpectedFixesConsolidated(), downsampler.getCountImportedTtl());
|
||||
Assert.assertEquals(importData.getExpectedFixesConsolidated(), callbackCallCount);
|
||||
try (final InputStream is = importData.getInputStream()) {
|
||||
bravoDataImporter.importFixes(is, (fixes, device) -> {
|
||||
for (DoubleVectorFix fix : fixes) {
|
||||
callbackCallCount++;
|
||||
sumRideHeightInMeters += new BravoFixImpl(fix).getRideHeight().getMeters();
|
||||
}
|
||||
}, "filename", "source", /* downsample */ true);
|
||||
Assert.assertEquals(importData.getExpectedFixesCount(), downsampler.getCountSourceTtl());
|
||||
Assert.assertEquals(importData.getExpectedFixesConsolidated(), downsampler.getCountImportedTtl());
|
||||
Assert.assertEquals(importData.getExpectedFixesConsolidated(), callbackCallCount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+28
-26
@@ -54,34 +54,36 @@ public class BravoExtendedDataImportTest extends AbstractBravoDataImportTest {
|
||||
@Test
|
||||
public void testReadingTwoLinesAndInterpolating() throws FormatNotSupportedException, IOException {
|
||||
DynamicBravoFixTrack<Competitor> track = new BravoFixTrackImpl<>(null, "Test Track", /* hasExtendedFixes */ true);
|
||||
bravoDataImporter.importFixes(new ByteArrayInputStream((
|
||||
HEADER_ORDER_DEFAULT+DUMMY_CONTENT+DUMMY_CONTENT2).getBytes(StandardCharsets.UTF_8)),
|
||||
(fixes, device) -> {
|
||||
for (DoubleVectorFix fix : fixes) {
|
||||
track.add(new BravoExtendedFixImpl(fix));
|
||||
try (final ByteArrayInputStream inputStream = new ByteArrayInputStream((
|
||||
HEADER_ORDER_DEFAULT+DUMMY_CONTENT+DUMMY_CONTENT2).getBytes(StandardCharsets.UTF_8))) {
|
||||
bravoDataImporter.importFixes(inputStream,
|
||||
(fixes, device) -> {
|
||||
for (DoubleVectorFix fix : fixes) {
|
||||
track.add(new BravoExtendedFixImpl(fix));
|
||||
}
|
||||
}, "filename", "source", /* downsample */ true);
|
||||
final TimePoint t1 = new MillisecondsTimePoint(1500648308500l);
|
||||
final TimePoint t2 = new MillisecondsTimePoint(1500648309500l);
|
||||
final BravoExtendedFix bef1, bef2;
|
||||
track.lockForRead();
|
||||
try {
|
||||
final Iterator<BravoFix> i = track.getFixes().iterator();
|
||||
bef1 = (BravoExtendedFix) i.next();
|
||||
bef2 = (BravoExtendedFix) i.next();
|
||||
} finally {
|
||||
track.unlockAfterRead();
|
||||
}
|
||||
}, "filename", "source", /* downsample */ true);
|
||||
final TimePoint t1 = new MillisecondsTimePoint(1500648308500l);
|
||||
final TimePoint t2 = new MillisecondsTimePoint(1500648309500l);
|
||||
final BravoExtendedFix bef1, bef2;
|
||||
track.lockForRead();
|
||||
try {
|
||||
final Iterator<BravoFix> i = track.getFixes().iterator();
|
||||
bef1 = (BravoExtendedFix) i.next();
|
||||
bef2 = (BravoExtendedFix) i.next();
|
||||
} finally {
|
||||
track.unlockAfterRead();
|
||||
assertEquals(t1, bef1.getTimePoint());
|
||||
assertEquals(t2, bef2.getTimePoint());
|
||||
assertEquals(0.915471, bef1.getPortRudderRake(), 0.00001);
|
||||
assertEquals(0.913729, bef2.getPortRudderRake(), 0.00001);
|
||||
assertEquals(0.915471, track.getPortRudderRakeIfAvailable(t1), 0.00001);
|
||||
assertEquals(0.913729, track.getPortRudderRakeIfAvailable(t2), 0.00001);
|
||||
assertEquals((0.915471+0.913729)/2., track.getPortRudderRakeIfAvailable(t1.plus(t1.until(t2).divide(2.))), 0.00001);
|
||||
assertEquals(new DegreeBearingImpl(-46.507845).getDegrees(), track.getMastRotationIfAvailable(t1).getDegrees(), 0.00001);
|
||||
assertEquals(new DegreeBearingImpl(-46.845317).getDegrees(), track.getMastRotationIfAvailable(t2).getDegrees(), 0.00001);
|
||||
assertEquals(new DegreeBearingImpl((-46.507845-46.845317)/2.).getDegrees(), track.getMastRotationIfAvailable(t1.plus(t1.until(t2).divide(2.))).getDegrees(), 0.00001);
|
||||
}
|
||||
assertEquals(t1, bef1.getTimePoint());
|
||||
assertEquals(t2, bef2.getTimePoint());
|
||||
assertEquals(0.915471, bef1.getPortRudderRake(), 0.00001);
|
||||
assertEquals(0.913729, bef2.getPortRudderRake(), 0.00001);
|
||||
assertEquals(0.915471, track.getPortRudderRakeIfAvailable(t1), 0.00001);
|
||||
assertEquals(0.913729, track.getPortRudderRakeIfAvailable(t2), 0.00001);
|
||||
assertEquals((0.915471+0.913729)/2., track.getPortRudderRakeIfAvailable(t1.plus(t1.until(t2).divide(2.))), 0.00001);
|
||||
assertEquals(new DegreeBearingImpl(-46.507845).getDegrees(), track.getMastRotationIfAvailable(t1).getDegrees(), 0.00001);
|
||||
assertEquals(new DegreeBearingImpl(-46.845317).getDegrees(), track.getMastRotationIfAvailable(t2).getDegrees(), 0.00001);
|
||||
assertEquals(new DegreeBearingImpl((-46.507845-46.845317)/2.).getDegrees(), track.getMastRotationIfAvailable(t1.plus(t1.until(t2).divide(2.))).getDegrees(), 0.00001);
|
||||
}
|
||||
|
||||
private enum ImportData implements ImportDataDefinition {
|
||||
|
||||
+27
-25
@@ -54,6 +54,10 @@ public class BaseBravoDataImporterImpl extends AbstractDoubleVectorFixImporter {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inputStream
|
||||
* the stream from which to read the fixes; this method will <em>not</em> close the stream; it's the
|
||||
* caller who is responsible for closing it. This, in particular, allows for usages with ZIP files
|
||||
* that would suffer from closing the stream here
|
||||
* @param downsample
|
||||
* if {@code true}, fixes will be down-sampled to a 1Hz frequency before being emitted to the
|
||||
* {@code callback}. Otherwise, all fixes read will be forwarded straight to the {@link Callback}.
|
||||
@@ -73,33 +77,31 @@ public class BaseBravoDataImporterImpl extends AbstractDoubleVectorFixImporter {
|
||||
}
|
||||
LOG.fine("Start parsing bravo file");
|
||||
AtomicLong lineNr = new AtomicLong();
|
||||
try (BufferedReader buffer = new BufferedReader(isr)) {
|
||||
String headerLine = null;
|
||||
headerSearch: while (headerLine == null) {
|
||||
LOG.fine("Searching for header in bravo file");
|
||||
String headerCandidate = buffer.readLine();
|
||||
lineNr.incrementAndGet();
|
||||
if (headerCandidate == null) {
|
||||
throw new RuntimeException("Missing required header in file " + filename);
|
||||
}
|
||||
if (headerCandidate.startsWith(BOF)) {
|
||||
LOG.fine("Found header");
|
||||
headerLine = headerCandidate;
|
||||
break headerSearch;
|
||||
}
|
||||
BufferedReader buffer = new BufferedReader(isr);
|
||||
String headerLine = null;
|
||||
headerSearch: while (headerLine == null) {
|
||||
LOG.fine("Searching for header in bravo file");
|
||||
String headerCandidate = buffer.readLine();
|
||||
lineNr.incrementAndGet();
|
||||
if (headerCandidate == null) {
|
||||
throw new RuntimeException("Missing required header in file " + filename);
|
||||
}
|
||||
if (headerCandidate.startsWith(BOF)) {
|
||||
LOG.fine("Found header");
|
||||
headerLine = headerCandidate;
|
||||
break headerSearch;
|
||||
}
|
||||
LOG.fine("Validate and parse header columns");
|
||||
final Map<String, Integer> colIndices = validateAndParseHeader(headerLine);
|
||||
DoubleFixProcessor downsampler = downsample ?
|
||||
createDownsamplingProcessor(callback, trackIdentifier) :
|
||||
fix->callback.addFixes(Collections.singleton(new DoubleVectorFixImpl(fix.getTimepoint(), fix.getFix())), trackIdentifier);
|
||||
buffer.lines().forEach(line -> {
|
||||
lineNr.incrementAndGet();
|
||||
downsampler.accept(parseLine(lineNr.get(), filename, line, colIndices));
|
||||
});
|
||||
downsampler.finish();
|
||||
buffer.close();
|
||||
}
|
||||
LOG.fine("Validate and parse header columns");
|
||||
final Map<String, Integer> colIndices = validateAndParseHeader(headerLine);
|
||||
DoubleFixProcessor downsampler = downsample ?
|
||||
createDownsamplingProcessor(callback, trackIdentifier) :
|
||||
fix->callback.addFixes(Collections.singleton(new DoubleVectorFixImpl(fix.getTimepoint(), fix.getFix())), trackIdentifier);
|
||||
buffer.lines().forEach(line -> {
|
||||
lineNr.incrementAndGet();
|
||||
downsampler.accept(parseLine(lineNr.get(), filename, line, colIndices));
|
||||
});
|
||||
downsampler.finish();
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.SEVERE, "Exception parsing bravo CSV file " + filename, e);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user