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.InputStream;
007import java.text.MessageFormat;
008
009import org.openstreetmap.josm.data.osm.DataSet;
010import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
011import org.openstreetmap.josm.data.osm.PrimitiveId;
012import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
013import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
014import org.openstreetmap.josm.gui.progress.ProgressMonitor;
015import org.openstreetmap.josm.tools.CheckParameterUtil;
016
017/**
018 * OsmServerObjectReader reads an individual object from the OSM server.
019 *
020 * It can either download the object including or not including its immediate children.
021 * The former case is called a "full download".
022 *
023 * It can also download a specific version of the object (however, "full" download is not possible
024 * in that case).
025 *
026 */
027public class OsmServerObjectReader extends OsmServerReader {
028    /** the id of the object to download */
029    private PrimitiveId id;
030    /** true if a full download is required, i.e. a download including the immediate children */
031    private boolean full;
032    /** the specific version number, if required (incompatible with full), or -1 else */
033    private int version;
034
035    /**
036     * Creates a new server object reader for a given id and a primitive type.
037     *
038     * @param id the object id. > 0 required.
039     * @param type the type. Must not be null.
040     * @param full true, if a full download is requested (i.e. a download including
041     * immediate children); false, otherwise
042     * @throws IllegalArgumentException if id <= 0
043     * @throws IllegalArgumentException if type is null
044     */
045    public OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full) {
046        this(id, type, full, -1);
047    }
048
049    /**
050     * Creates a new server object reader for a given id and a primitive type.
051     *
052     * @param id the object id. > 0 required.
053     * @param type the type. Must not be null.
054     * @param version the specific version number, if required; -1, otherwise
055     * @throws IllegalArgumentException if id <= 0
056     * @throws IllegalArgumentException if type is null
057     */
058    public OsmServerObjectReader(long id, OsmPrimitiveType type, int version) {
059        this(id, type, false, version);
060    }
061
062    protected OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full, int version) {
063        if (id <= 0)
064            throw new IllegalArgumentException(MessageFormat.format("Expected value > 0 for parameter ''{0}'', got {1}", "id", id));
065        CheckParameterUtil.ensureParameterNotNull(type, "type");
066        this.id = new SimplePrimitiveId(id, type);
067        this.full = full;
068        this.version = version;
069    }
070
071    /**
072     * Creates a new server object reader for an object with the given <code>id</code>
073     *
074     * @param id the object id. Must not be null. Unique id &gt; 0 required.
075     * @param full true, if a full download is requested (i.e. a download including
076     * immediate children); false, otherwise
077     * @throws IllegalArgumentException if id is null
078     * @throws IllegalArgumentException if id.getUniqueId() &lt;= 0
079     */
080    public OsmServerObjectReader(PrimitiveId id, boolean full) {
081        this(id, full, -1);
082    }
083
084    /**
085     * Creates a new server object reader for an object with the given <code>id</code>
086     *
087     * @param id the object id. Must not be null. Unique id &gt; 0 required.
088     * @param version the specific version number, if required; -1, otherwise
089     * @throws IllegalArgumentException if id is null
090     * @throws IllegalArgumentException if id.getUniqueId() &lt;= 0
091     */
092    public OsmServerObjectReader(PrimitiveId id, int version) {
093        this(id, false, version);
094    }
095
096    protected OsmServerObjectReader(PrimitiveId id, boolean full, int version) {
097        CheckParameterUtil.ensureValidPrimitiveId(id, "id");
098        this.id = id;
099        this.full = full;
100        this.version = version;
101    }
102
103    /**
104     * Downloads and parses the data.
105     *
106     * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
107     * @return the downloaded data
108     * @throws OsmTransferException if any error occurs during dialog with OSM API
109     */
110    @Override
111    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
112        if (progressMonitor == null) {
113            progressMonitor = NullProgressMonitor.INSTANCE;
114        }
115        progressMonitor.beginTask("", 1);
116        try {
117            progressMonitor.indeterminateSubTask(tr("Downloading OSM data..."));
118            StringBuilder sb = new StringBuilder();
119            sb.append(id.getType().getAPIName())
120              .append('/')
121              .append(id.getUniqueId());
122            if (full && !id.getType().equals(OsmPrimitiveType.NODE)) {
123                sb.append("/full");
124            } else if (version > 0) {
125                sb.append('/').append(version);
126            }
127
128            try (InputStream in = getInputStream(sb.toString(), progressMonitor.createSubTaskMonitor(1, true))) {
129                if (in == null)
130                    return null;
131                return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
132            }
133        } catch (OsmTransferException e) {
134            if (cancel) return null;
135            throw e;
136        } catch (Exception e) {
137            if (cancel) return null;
138            throw new OsmTransferException(e);
139        } finally {
140            progressMonitor.finishTask();
141            activeConnection = null;
142        }
143    }
144}