Skip to content
Snippets Groups Projects
Commit 56cd327f authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Support for importing from URL

parent 6a111267
No related branches found
No related tags found
No related merge requests found
Showing
with 99 additions and 43 deletions
...@@ -4,6 +4,7 @@ import java.io.File; ...@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
...@@ -77,8 +78,8 @@ public class App { ...@@ -77,8 +78,8 @@ public class App {
private IDocumentPersistence<Collection<GeoLocations>, File> documentPersistence = new IDocumentPersistence<Collection<GeoLocations>, File>() { private IDocumentPersistence<Collection<GeoLocations>, File> documentPersistence = new IDocumentPersistence<Collection<GeoLocations>, File>() {
@Override @Override
public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception { public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
return geoLocationsLoader.loadLocations(new FileInputStream(documentLocation)); return geoLocationsLoader.loadLocations(inputStream);
} }
@Override @Override
...@@ -106,20 +107,24 @@ public class App { ...@@ -106,20 +107,24 @@ public class App {
return new ArrayList<GeoLocations>(); return new ArrayList<GeoLocations>();
} }
public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception { protected InputStream toInputStream(File storage) throws IOException {
return documentPersistence.loadDocument(documentLocation); return new FileInputStream(storage);
}
public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
return documentPersistence.loadDocument(inputStream);
} }
public void saveDocument(Collection<GeoLocations> document, File documentLocation) throws Exception { public void saveDocument(Collection<GeoLocations> document, File documentLocation) throws Exception {
documentPersistence.saveDocument(document, documentLocation); documentPersistence.saveDocument(document, documentLocation);
} }
public Collection<IDocumentImporter<File>> getDocumentImporters() { public Collection<IDocumentImporter> getDocumentImporters() {
return documentLoaders.stream().map(loader -> new IDocumentImporter<File>() { return documentLoaders.stream().map(loader -> new IDocumentImporter() {
@Override @Override
public void importDocument(File file) throws IOException { public void importDocument(InputStream inputStream) throws IOException {
try { try {
setDocumentAndLocation(loader.loadDocument(file), null); setDocumentAndLocation(loader.loadDocument(inputStream), null);
} catch (Exception e) { } catch (Exception e) {
throw new IOException(e); throw new IOException(e);
} }
...@@ -132,17 +137,17 @@ public class App { ...@@ -132,17 +137,17 @@ public class App {
return documentStorage; return documentStorage;
} }
private Collection<IDocumentLoader<Collection<GeoLocations>, File>> documentLoaders = Arrays.asList( private Collection<IDocumentLoader<Collection<GeoLocations>>> documentLoaders = Arrays.asList(
new IDocumentLoader<Collection<GeoLocations>, File>() { new IDocumentLoader<Collection<GeoLocations>>() {
private GpxDocumentConverter gpxConverter = new GpxDocumentConverter(); private GpxDocumentConverter gpxConverter = new GpxDocumentConverter();
@Override @Override
public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception { public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
return gpxConverter.loadDocument(documentLocation); return gpxConverter.loadDocument(inputStream);
} }
} }
); );
public Iterable<IDocumentLoader<Collection<GeoLocations>, File>> getDocumentLoaders() { public Iterable<IDocumentLoader<Collection<GeoLocations>>> getDocumentLoaders() {
return documentLoaders; return documentLoaders;
} }
} }
package tdt4140.gr1800.app.doc; package tdt4140.gr1800.app.doc;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
...@@ -61,10 +62,12 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L>, ...@@ -61,10 +62,12 @@ public abstract class DocumentStorageImpl<D, L> implements IDocumentStorage<L>,
setDocumentAndLocation(createDocument(), null); setDocumentAndLocation(createDocument(), null);
} }
protected abstract InputStream toInputStream(L storage) throws IOException;
@Override @Override
public void openDocument(L storage) throws IOException { public void openDocument(L storage) throws IOException {
try { try {
setDocumentAndLocation(loadDocument(storage), storage); setDocumentAndLocation(loadDocument(toInputStream(storage)), storage);
} catch (Exception e) { } catch (Exception e) {
throw new IOException(e); throw new IOException(e);
} }
......
package tdt4140.gr1800.app.doc; package tdt4140.gr1800.app.doc;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
public interface IDocumentImporter<L> { public interface IDocumentImporter {
public void importDocument(L documentLocation) throws IOException; public void importDocument(InputStream inputStream) throws IOException;
} }
package tdt4140.gr1800.app.doc; package tdt4140.gr1800.app.doc;
public interface IDocumentLoader<D, L> { import java.io.InputStream;
public D loadDocument(L documentLocation) throws Exception;
public interface IDocumentLoader<D> {
public D loadDocument(InputStream inputStream) throws Exception;
} }
package tdt4140.gr1800.app.doc; package tdt4140.gr1800.app.doc;
public interface IDocumentPersistence<D, L> extends IDocumentLoader<D, L>, IDocumentSaver<D, L> { public interface IDocumentPersistence<D, L> extends IDocumentLoader<D>, IDocumentSaver<D, L> {
} }
...@@ -14,5 +14,5 @@ public interface IDocumentStorage<L> { ...@@ -14,5 +14,5 @@ public interface IDocumentStorage<L> {
public void openDocument(L documentLocation) throws IOException; public void openDocument(L documentLocation) throws IOException;
public void saveDocument() throws IOException; public void saveDocument() throws IOException;
public Collection<IDocumentImporter<L>> getDocumentImporters(); public Collection<IDocumentImporter> getDocumentImporters();
} }
package tdt4140.gr1800.app.gpx; package tdt4140.gr1800.app.gpx;
import java.io.File; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -14,13 +14,13 @@ import tdt4140.gr1800.app.core.GeoLocations; ...@@ -14,13 +14,13 @@ import tdt4140.gr1800.app.core.GeoLocations;
import tdt4140.gr1800.app.core.LatLong; import tdt4140.gr1800.app.core.LatLong;
import tdt4140.gr1800.app.doc.IDocumentLoader; import tdt4140.gr1800.app.doc.IDocumentLoader;
public class GpxDocumentConverter implements IDocumentLoader<Collection<GeoLocations>, File> { public class GpxDocumentConverter implements IDocumentLoader<Collection<GeoLocations>> {
private GpxDocumentLoader gpxLoader = new GpxDocumentLoader(); private GpxDocumentLoader gpxLoader = new GpxDocumentLoader();
@Override @Override
public Collection<GeoLocations> loadDocument(File documentLocation) throws Exception { public Collection<GeoLocations> loadDocument(InputStream inputStream) throws Exception {
GPX gpx = gpxLoader.loadDocument(documentLocation.toURI().toURL()); GPX gpx = gpxLoader.loadDocument(inputStream);
return convert(gpx); return convert(gpx);
} }
......
package tdt4140.gr1800.app.gpx; package tdt4140.gr1800.app.gpx;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL;
import io.jenetics.jpx.GPX; import io.jenetics.jpx.GPX;
import tdt4140.gr1800.app.doc.IDocumentLoader; import tdt4140.gr1800.app.doc.IDocumentLoader;
public class GpxDocumentLoader implements IDocumentLoader<GPX, URL> { public class GpxDocumentLoader implements IDocumentLoader<GPX> {
@Override
public GPX loadDocument(InputStream inputStream) throws Exception { public GPX loadDocument(InputStream inputStream) throws Exception {
return GPX.read(inputStream, true); return GPX.read(inputStream, true);
} }
@Override
public GPX loadDocument(URL documentLocation) throws Exception {
return loadDocument(documentLocation.openStream());
}
} }
...@@ -2,7 +2,6 @@ package tdt4140.gr1800.app.core; ...@@ -2,7 +2,6 @@ package tdt4140.gr1800.app.core;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
......
...@@ -25,7 +25,7 @@ public class GpxPersistenceTest { ...@@ -25,7 +25,7 @@ public class GpxPersistenceTest {
@Test @Test
public void testLoadDocument() { public void testLoadDocument() {
try { try {
GPX gpx = loader.loadDocument(getClass().getResource("sample1.gpx")); GPX gpx = loader.loadDocument(getClass().getResourceAsStream("sample1.gpx"));
Assert.assertEquals(1, gpx.getTracks().size()); Assert.assertEquals(1, gpx.getTracks().size());
Assert.assertEquals(1, gpx.getTracks().get(0).getSegments().size()); Assert.assertEquals(1, gpx.getTracks().get(0).getSegments().size());
Assert.assertEquals(3, gpx.getTracks().get(0).getSegments().get(0).getPoints().size()); Assert.assertEquals(3, gpx.getTracks().get(0).getSegments().get(0).getPoints().size());
...@@ -37,7 +37,7 @@ public class GpxPersistenceTest { ...@@ -37,7 +37,7 @@ public class GpxPersistenceTest {
@Test @Test
public void testConvertSample1() { public void testConvertSample1() {
try { try {
GPX gpx = loader.loadDocument(getClass().getResource("sample1.gpx")); GPX gpx = loader.loadDocument(getClass().getResourceAsStream("sample1.gpx"));
Collection<GeoLocations> geoLocations = converter.convert(gpx); Collection<GeoLocations> geoLocations = converter.convert(gpx);
Assert.assertEquals(1, geoLocations.size()); Assert.assertEquals(1, geoLocations.size());
GeoLocations track = geoLocations.iterator().next(); GeoLocations track = geoLocations.iterator().next();
...@@ -53,7 +53,7 @@ public class GpxPersistenceTest { ...@@ -53,7 +53,7 @@ public class GpxPersistenceTest {
@Test @Test
public void testConvertAchterbroekRoute() { public void testConvertAchterbroekRoute() {
try { try {
GPX gpx = loader.loadDocument(getClass().getResource("Achterbroek-route.gpx")); GPX gpx = loader.loadDocument(getClass().getResourceAsStream("Achterbroek-route.gpx"));
Collection<GeoLocations> geoLocations = converter.convert(gpx); Collection<GeoLocations> geoLocations = converter.convert(gpx);
Assert.assertEquals(2, geoLocations.size()); Assert.assertEquals(2, geoLocations.size());
Iterator<GeoLocations> iterator = geoLocations.iterator(); Iterator<GeoLocations> iterator = geoLocations.iterator();
...@@ -74,7 +74,7 @@ public class GpxPersistenceTest { ...@@ -74,7 +74,7 @@ public class GpxPersistenceTest {
@Test @Test
public void testConvertAchterbroekTrack() { public void testConvertAchterbroekTrack() {
try { try {
GPX gpx = loader.loadDocument(getClass().getResource("Achterbroek-track.gpx")); GPX gpx = loader.loadDocument(getClass().getResourceAsStream("Achterbroek-track.gpx"));
Collection<GeoLocations> geoLocations = converter.convert(gpx); Collection<GeoLocations> geoLocations = converter.convert(gpx);
Assert.assertEquals(2, geoLocations.size()); Assert.assertEquals(2, geoLocations.size());
Iterator<GeoLocations> iterator = geoLocations.iterator(); Iterator<GeoLocations> iterator = geoLocations.iterator();
......
package tdt4140.gr1800.app.ui; package tdt4140.gr1800.app.ui;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Menu; import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import javafx.scene.control.TextInputDialog;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import tdt4140.gr1800.app.doc.IDocumentImporter; import tdt4140.gr1800.app.doc.IDocumentImporter;
import tdt4140.gr1800.app.doc.IDocumentStorage; import tdt4140.gr1800.app.doc.IDocumentStorage;
...@@ -130,22 +135,65 @@ public class FileMenuController { ...@@ -130,22 +135,65 @@ public class FileMenuController {
} }
@FXML @FXML
public void handleImportAction() { public void handleFileImportAction() {
FileChooser fileChooser = getFileChooser(); FileChooser fileChooser = getFileChooser();
File selection = fileChooser.showOpenDialog(null); File selection = fileChooser.showOpenDialog(null);
// String path = selection.getPath(); // String path = selection.getPath();
// int pos = path.lastIndexOf('.'); // int pos = path.lastIndexOf('.');
// String ext = (pos > 0 ? path.substring(pos + 1) : null); // String ext = (pos > 0 ? path.substring(pos + 1) : null);
handleImportAction(selection); handleFileImportAction(selection);
} }
void handleImportAction(File selection) { void handleFileImportAction(File selection) {
for (IDocumentImporter<File> importer : documentStorage.getDocumentImporters()) { for (IDocumentImporter importer : documentStorage.getDocumentImporters()) {
try { try {
importer.importDocument(selection); importer.importDocument(new FileInputStream(selection));
break; break;
} catch (Exception e) { } catch (Exception e) {
} }
} }
} }
private TextInputDialog inputDialog;
@FXML
public void handleURLImportAction() {
if (inputDialog == null) {
inputDialog = new TextInputDialog();
}
inputDialog.setTitle("Import from URL");
inputDialog.setHeaderText("Enter URL to import from");
inputDialog.setContentText("Enter URL: ");
// https://developer.garmin.com/downloads/connect-api/sample_file.gpx
URL url = null;
while (url == null) {
Optional<String> result = inputDialog.showAndWait();
if (! result.isPresent()) {
return;
}
try {
url = new URL(result.get());
if (handleURLImportAction(url)) {
return;
}
url = null;
inputDialog.setHeaderText("Problems reading it...");
inputDialog.setContentText("Enter another URL: ");
} catch (MalformedURLException e1) {
inputDialog.setContentText("Enter a valid URL: ");
}
}
}
boolean handleURLImportAction(URL url) {
for (IDocumentImporter importer : documentStorage.getDocumentImporters()) {
try {
importer.importDocument(url.openStream());
return true;
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
return false;
}
} }
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
<MenuItem text="Save As..." onAction="#handleSaveAsAction"/> <MenuItem text="Save As..." onAction="#handleSaveAsAction"/>
<MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/> <MenuItem text="Save Copy As..." onAction="#handleSaveCopyAsAction"/>
<SeparatorMenuItem/> <SeparatorMenuItem/>
<MenuItem text="Import..." onAction="#handleImportAction"/> <Menu text="Import">
<MenuItem text="File..." onAction="#handleFileImportAction"/>
<MenuItem text="URL..." onAction="#handleURLImportAction"/>
</Menu>
</items> </items>
</Menu> </Menu>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment