001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.io;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.io.File;
007    import java.io.FileInputStream;
008    import java.io.FileNotFoundException;
009    import java.io.IOException;
010    import java.io.InputStream;
011    
012    import javax.swing.JOptionPane;
013    
014    import org.openstreetmap.josm.Main;
015    import org.openstreetmap.josm.actions.ExtensionFileFilter;
016    import org.openstreetmap.josm.data.osm.DataSet;
017    import org.openstreetmap.josm.gui.layer.OsmDataLayer;
018    import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
019    import org.openstreetmap.josm.gui.progress.ProgressMonitor;
020    import org.openstreetmap.josm.gui.util.GuiHelper;
021    
022    public 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        public OsmImporter() {
047            super(FILE_FILTER);
048        }
049    
050        public OsmImporter(ExtensionFileFilter filter) {
051            super(filter);
052        }
053    
054        @Override
055        public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
056            FileInputStream in = null;
057            try {
058                in = new FileInputStream(file);
059                importData(in, file);
060            } catch (FileNotFoundException e) {
061                e.printStackTrace();
062                throw new IOException(tr("File ''{0}'' does not exist.", file.getName()));
063            } finally {
064                if (in != null) {
065                    in.close();
066                }
067            }
068        }
069    
070        protected void importData(InputStream in, final File associatedFile) throws IllegalDataException {
071            final OsmImporterData data = loadLayer(in, associatedFile,
072                    associatedFile == null ? OsmDataLayer.createNewName() : associatedFile.getName(), NullProgressMonitor.INSTANCE);
073    
074            // FIXME: remove UI stuff from IO subsystem
075            GuiHelper.runInEDT(new Runnable() {
076                @Override
077                public void run() {
078                    Main.main.addLayer(data.layer);
079                    data.postLayerTask.run();
080                    data.layer.onPostLoadFromFile();
081                }
082            });
083        }
084    
085        /**
086         * Load osm data layer from InputStream.
087         * associatedFile can be null if the stream does not come from a file.
088         */
089        public OsmImporterData loadLayer(InputStream in, final File associatedFile, final String layerName, ProgressMonitor progressMonitor) throws IllegalDataException {
090            final DataSet dataSet = parseDataSet(in, progressMonitor);
091            if (dataSet == null) {
092                throw new IllegalDataException(tr("Invalid dataset"));
093            }
094            OsmDataLayer layer = createLayer(dataSet, associatedFile, layerName);
095            Runnable postLayerTask = createPostLayerTask(dataSet, associatedFile, layerName, layer);
096            return new OsmImporterData(layer, postLayerTask);
097        }
098    
099        protected DataSet parseDataSet(InputStream in, ProgressMonitor progressMonitor) throws IllegalDataException {
100            return OsmReader.parseDataSet(in, progressMonitor);
101        }
102    
103        protected OsmDataLayer createLayer(final DataSet dataSet, final File associatedFile, final String layerName) {
104            return new OsmDataLayer(dataSet, layerName, associatedFile);
105        }
106    
107        protected Runnable createPostLayerTask(final DataSet dataSet, final File associatedFile, final String layerName, final OsmDataLayer layer) {
108            return new Runnable() {
109                @Override
110                public void run() {
111                    if (dataSet.allPrimitives().isEmpty()) {
112                        String msg;
113                        if (associatedFile == null) {
114                            msg = tr("No data found for layer ''{0}''.", layerName);
115                        } else {
116                            msg = tr("No data found in file ''{0}''.", associatedFile.getPath());
117                        }
118                        JOptionPane.showMessageDialog(
119                                Main.parent,
120                                msg,
121                                tr("Open OSM file"),
122                                JOptionPane.INFORMATION_MESSAGE);
123                    }
124                    layer.onPostLoadFromFile();
125                }
126            };
127        }
128    }