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.FileNotFoundException;
008import java.io.IOException;
009import java.io.InputStream;
010
011import javax.swing.JOptionPane;
012
013import org.openstreetmap.josm.actions.ExtensionFileFilter;
014import org.openstreetmap.josm.data.osm.DataSet;
015import org.openstreetmap.josm.data.osm.NoteData;
016import org.openstreetmap.josm.gui.MainApplication;
017import org.openstreetmap.josm.gui.layer.Layer;
018import org.openstreetmap.josm.gui.layer.NoteLayer;
019import org.openstreetmap.josm.gui.layer.OsmDataLayer;
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.IllegalDataException;
024import org.openstreetmap.josm.io.OsmChangeReader;
025import org.openstreetmap.josm.tools.Logging;
026import org.openstreetmap.josm.tools.Pair;
027
028/**
029 * File importer that reads OSM change files (*.osc).
030 * @see <a href="http://wiki.openstreetmap.org/wiki/OsmChange">OsmChange</a>
031 */
032public class OsmChangeImporter extends FileImporter {
033
034    /**
035     * File filter for OsmChange files.
036     */
037    public static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
038            "osc", "osc", tr("OsmChange File"), true);
039
040    /**
041     * Constructs a new {@code OsmChangeImporter} with default file filter.
042     */
043    public OsmChangeImporter() {
044        super(FILE_FILTER);
045    }
046
047    /**
048     * Constructs a new {@code OsmChangeImporter} with custom file filter.
049     * @param filter file filter
050     */
051    public OsmChangeImporter(ExtensionFileFilter filter) {
052        super(filter);
053    }
054
055    @Override
056    public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
057        try {
058            importData(Compression.getUncompressedFileInputStream(file), file, progressMonitor);
059        } catch (FileNotFoundException e) {
060            Logging.error(e);
061            throw new IOException(tr("File ''{0}'' does not exist.", file.getName()), e);
062        }
063    }
064
065    protected void importData(InputStream in, final File associatedFile, ProgressMonitor progressMonitor) throws IllegalDataException {
066        final Pair<DataSet, NoteData> p = OsmChangeReader.parseDataSetAndNotes(in, progressMonitor);
067        final boolean hasOsmData = p.a != null && !p.a.allPrimitives().isEmpty();
068        final boolean hasNotes = p.b != null && !p.b.getNotes().isEmpty();
069        if (hasOsmData) {
070            addLayer(new OsmDataLayer(p.a, associatedFile.getName(), associatedFile));
071        }
072        if (hasNotes) {
073            addLayer(new NoteLayer(p.b, associatedFile.getName()));
074        }
075        if (!hasOsmData && !hasNotes) {
076            // FIXME: remove UI stuff from IO subsystem
077            GuiHelper.runInEDT(() ->
078                JOptionPane.showMessageDialog(
079                        MainApplication.getMainFrame(),
080                        tr("No data found in file {0}.", associatedFile.getPath()),
081                        tr("Open OsmChange file"),
082                        JOptionPane.INFORMATION_MESSAGE)
083            );
084        }
085    }
086
087    protected void addLayer(final Layer layer) {
088        // FIXME: remove UI stuff from IO subsystem
089        GuiHelper.runInEDT(() -> {
090            MainApplication.getLayerManager().addLayer(layer);
091            layer.onPostLoadFromFile();
092        });
093    }
094}