001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.io.File; 007import java.io.FileNotFoundException; 008import java.io.IOException; 009import java.io.InputStream; 010 011import javax.swing.JOptionPane; 012 013import org.openstreetmap.josm.Main; 014import org.openstreetmap.josm.actions.ExtensionFileFilter; 015import org.openstreetmap.josm.data.osm.DataSet; 016import org.openstreetmap.josm.gui.layer.OsmDataLayer; 017import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 018import org.openstreetmap.josm.gui.progress.ProgressMonitor; 019import org.openstreetmap.josm.gui.util.GuiHelper; 020import org.openstreetmap.josm.tools.Utils; 021 022public class OsmImporter extends FileImporter { 023 024 public static final ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter( 025 "osm,xml", "osm", tr("OSM Server Files") + " (*.osm *.xml)"); 026 027 public static class OsmImporterData { 028 029 private OsmDataLayer layer; 030 private Runnable postLayerTask; 031 032 public OsmImporterData(OsmDataLayer layer, Runnable postLayerTask) { 033 this.layer = layer; 034 this.postLayerTask = postLayerTask; 035 } 036 037 public OsmDataLayer getLayer() { 038 return layer; 039 } 040 041 public Runnable getPostLayerTask() { 042 return postLayerTask; 043 } 044 } 045 046 /** 047 * Constructs a new {@code OsmImporter}. 048 */ 049 public OsmImporter() { 050 super(FILE_FILTER); 051 } 052 053 public OsmImporter(ExtensionFileFilter filter) { 054 super(filter); 055 } 056 057 /** 058 * Imports OSM data from file 059 * @param file file to read data from 060 * @param progressMonitor handler for progress monitoring and canceling 061 */ 062 @Override 063 public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException { 064 try (InputStream in = Compression.getUncompressedFileInputStream(file)) { 065 importData(in, file, progressMonitor); 066 } catch (FileNotFoundException e) { 067 Main.error(e); 068 throw new IOException(tr("File ''{0}'' does not exist.", file.getName()), e); 069 } 070 } 071 072 /** 073 * Imports OSM data from stream 074 * @param in input stream 075 * @param associatedFile filename of data 076 */ 077 protected void importData(InputStream in, final File associatedFile) throws IllegalDataException { 078 importData(in, associatedFile, NullProgressMonitor.INSTANCE); 079 } 080 081 /** 082 * Imports OSM data from stream 083 * @param in input stream 084 * @param associatedFile filename of data (layer name will be generated from name of file) 085 * @param pm handler for progress monitoring and canceling 086 */ 087 protected void importData(InputStream in, final File associatedFile, ProgressMonitor pm) throws IllegalDataException { 088 final OsmImporterData data = loadLayer(in, associatedFile, 089 associatedFile == null ? OsmDataLayer.createNewName() : associatedFile.getName(), pm); 090 091 // FIXME: remove UI stuff from IO subsystem 092 GuiHelper.runInEDT(new Runnable() { 093 @Override 094 public void run() { 095 Main.main.addLayer(data.layer); 096 data.postLayerTask.run(); 097 data.layer.onPostLoadFromFile(); 098 } 099 }); 100 } 101 102 /** 103 * Load osm data layer from InputStream. 104 * @param in input stream 105 * @param associatedFile filename of data (can be <code>null</code> if the stream does not come from a file) 106 * @param layerName name of generated layer 107 * @param progressMonitor handler for progress monitoring and canceling 108 */ 109 public OsmImporterData loadLayer(InputStream in, final File associatedFile, final String layerName, ProgressMonitor progressMonitor) throws IllegalDataException { 110 final DataSet dataSet = parseDataSet(in, progressMonitor); 111 if (dataSet == null) { 112 throw new IllegalDataException(tr("Invalid dataset")); 113 } 114 OsmDataLayer layer = createLayer(dataSet, associatedFile, layerName); 115 Runnable postLayerTask = createPostLayerTask(dataSet, associatedFile, layerName, layer); 116 return new OsmImporterData(layer, postLayerTask); 117 } 118 119 protected DataSet parseDataSet(InputStream in, ProgressMonitor progressMonitor) throws IllegalDataException { 120 return OsmReader.parseDataSet(in, progressMonitor); 121 } 122 123 protected OsmDataLayer createLayer(final DataSet dataSet, final File associatedFile, final String layerName) { 124 return new OsmDataLayer(dataSet, layerName, associatedFile); 125 } 126 127 protected Runnable createPostLayerTask(final DataSet dataSet, final File associatedFile, final String layerName, final OsmDataLayer layer) { 128 return new Runnable() { 129 @Override 130 public void run() { 131 if (dataSet.allPrimitives().isEmpty()) { 132 String msg; 133 if (associatedFile == null) { 134 msg = tr("No data found for layer ''{0}''.", layerName); 135 } else { 136 msg = tr("No data found in file ''{0}''.", associatedFile.getPath()); 137 } 138 JOptionPane.showMessageDialog( 139 Main.parent, 140 msg, 141 tr("Open OSM file"), 142 JOptionPane.INFORMATION_MESSAGE); 143 } 144 layer.onPostLoadFromFile(); 145 } 146 }; 147 } 148}