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.InvalidClassException;
009import java.io.ObjectInputStream;
010import java.nio.file.Files;
011import java.util.Map;
012
013import org.openstreetmap.josm.actions.ExtensionFileFilter;
014import org.openstreetmap.josm.data.StructUtils;
015import org.openstreetmap.josm.data.coor.EastNorth;
016import org.openstreetmap.josm.data.imagery.ImageryInfo;
017import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryPreferenceEntry;
018import org.openstreetmap.josm.gui.MainApplication;
019import org.openstreetmap.josm.gui.layer.ImageryLayer;
020import org.openstreetmap.josm.gui.progress.ProgressMonitor;
021import org.openstreetmap.josm.gui.util.GuiHelper;
022import org.openstreetmap.josm.io.IllegalDataException;
023import org.openstreetmap.josm.tools.CheckParameterUtil;
024
025/**
026 * Import a WMS layer from a serialized binary file previously exported via {@link WMSLayerExporter}.
027 * @since 5457
028 */
029public class WMSLayerImporter extends FileImporter {
030
031    /**
032     * The file filter used in "open" and "save" dialogs for WMS layers.
033     */
034    public static final ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter(
035            "wms", "wms", tr("WMS Files (*.wms)"));
036
037    /**
038     * Constructs a new {@code WMSLayerImporter}.
039     */
040    public WMSLayerImporter() {
041        super(FILE_FILTER);
042    }
043
044    @Override
045    public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
046        CheckParameterUtil.ensureParameterNotNull(file, "file");
047        final EastNorth zoomTo;
048        ImageryInfo info = null;
049        final ImageryLayer layer;
050
051        try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
052            int sfv = ois.readInt();
053            if (sfv < 5) {
054                throw new InvalidClassException(tr("Unsupported WMS file version; found {0}, expected {1}", sfv, 5));
055            } else if (sfv == 5) {
056                ois.readInt(); // dax - not needed
057                ois.readInt(); // day - not needed
058                zoomTo = null;
059
060                int imageSize = ois.readInt();
061                double pixelPerDegree = ois.readDouble();
062
063                String name = (String) ois.readObject();
064                String extendedUrl = (String) ois.readObject();
065
066                info = new ImageryInfo(name);
067                info.setExtendedUrl(extendedUrl);
068                info.setPixelPerDegree(pixelPerDegree);
069                info.setTileSize(imageSize);
070            } else if (sfv == WMSLayerExporter.CURRENT_FILE_VERSION) {
071                zoomTo = (EastNorth) ois.readObject();
072
073                @SuppressWarnings("unchecked")
074                ImageryPreferenceEntry entry = StructUtils.deserializeStruct(
075                        (Map<String, String>) ois.readObject(),
076                        ImageryPreferenceEntry.class);
077                info = new ImageryInfo(entry);
078            } else {
079                throw new InvalidClassException(tr("Unsupported WMS file version; found {0}, expected {1}", sfv, 6));
080            }
081        } catch (ClassNotFoundException e) {
082            throw new IllegalDataException(e);
083        }
084        layer = ImageryLayer.create(info);
085
086
087        // FIXME: remove UI stuff from IO subsystem
088        GuiHelper.runInEDT(() -> {
089            MainApplication.getLayerManager().addLayer(layer);
090            if (zoomTo != null) {
091                MainApplication.getMap().mapView.zoomTo(zoomTo);
092            }
093        });
094    }
095}