001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.io.importexport; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.io.File; 007import java.io.IOException; 008import java.io.InputStream; 009import java.util.Objects; 010 011import javax.swing.JOptionPane; 012import javax.swing.SwingUtilities; 013 014import org.openstreetmap.josm.actions.ExtensionFileFilter; 015import org.openstreetmap.josm.gui.HelpAwareOptionPane; 016import org.openstreetmap.josm.gui.MainApplication; 017import org.openstreetmap.josm.gui.Notification; 018import org.openstreetmap.josm.gui.layer.GpxLayer; 019import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; 020import org.openstreetmap.josm.gui.progress.ProgressMonitor; 021import org.openstreetmap.josm.gui.util.GuiHelper; 022import org.openstreetmap.josm.io.Compression; 023import org.openstreetmap.josm.io.IGpxReader; 024import org.openstreetmap.josm.spi.preferences.Config; 025import org.xml.sax.SAXException; 026 027/** 028 * Abstraction of {@link NMEAImporter}, {@link OziWptImporter} and {@link RtkLibImporter}. 029 * @param <T> GPX reader type 030 * @since 18179 031 */ 032public abstract class GpxLikeImporter<T extends IGpxReader> extends FileImporter { 033 034 private Class<T> klass; 035 036 /** 037 * Constructs a new {@code GpxLikeImporter}. 038 * @param filter The extension file filter 039 * @param klass type class 040 */ 041 protected GpxLikeImporter(ExtensionFileFilter filter, Class<T> klass) { 042 super(Objects.requireNonNull(filter)); 043 this.klass = Objects.requireNonNull(klass); 044 } 045 046 @Override 047 public final void importData(File file, ProgressMonitor progressMonitor) throws IOException { 048 final String fn = file.getName(); 049 try (InputStream fis = Compression.getUncompressedFileInputStream(file)) { 050 final T r = buildAndParse(fis, klass); 051 if (r.getNumberOfCoordinates() > 0) { 052 r.getGpxData().storageFile = file; 053 final GpxLayer gpxLayer = new GpxLayer(r.getGpxData(), fn, true); 054 final File fileFinal = file; 055 056 GuiHelper.runInEDT(() -> { 057 MainApplication.getLayerManager().addLayer(gpxLayer); 058 if (Config.getPref().getBoolean("marker.makeautomarkers", true)) { 059 MarkerLayer ml = new MarkerLayer(r.getGpxData(), tr("Markers from {0}", fn), fileFinal, gpxLayer); 060 if (!ml.data.isEmpty()) { 061 MainApplication.getLayerManager().addLayer(ml); 062 } 063 } 064 }); 065 } 066 showInfobox(r.getNumberOfCoordinates() > 0, r); 067 } 068 } 069 070 protected final void showInfobox(boolean success, T r) { 071 final StringBuilder msg = new StringBuilder(160).append("<html>") 072 .append(tr("Coordinates imported: {0}", r.getNumberOfCoordinates())); 073 appendInfoboxContent(msg, success, r); 074 msg.append("</html>"); 075 if (success) { 076 SwingUtilities.invokeLater(() -> new Notification( 077 "<h3>" + tr("Import success:") + "</h3>" + msg.toString()) 078 .setIcon(JOptionPane.INFORMATION_MESSAGE) 079 .show()); 080 } else { 081 HelpAwareOptionPane.showMessageDialogInEDT( 082 MainApplication.getMainFrame(), 083 msg.toString(), 084 tr("Import failure!"), 085 JOptionPane.ERROR_MESSAGE, null); 086 } 087 } 088 089 protected void appendInfoboxContent(StringBuilder msg, boolean success, T r) { 090 // Complete if needed 091 } 092 093 protected static final <T extends IGpxReader> T buildAndParse(InputStream fis, Class<T> klass) throws IOException { 094 try { 095 final T r = klass.getConstructor(InputStream.class).newInstance(fis); 096 r.parse(true); 097 return r; 098 } catch (SAXException | ReflectiveOperationException | IllegalArgumentException | SecurityException e) { 099 throw new IOException(e); 100 } 101 } 102}