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 thrown if id <= 0 043 * @throws IllegalArgumentException thrown if type is null 044 */ 045 public OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full) throws IllegalArgumentException { 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 thrown if id <= 0 056 * @throws IllegalArgumentException thrown if type is null 057 */ 058 public OsmServerObjectReader(long id, OsmPrimitiveType type, int version) throws IllegalArgumentException { 059 this(id, type, false, version); 060 } 061 062 protected OsmServerObjectReader(long id, OsmPrimitiveType type, boolean full, int version) throws IllegalArgumentException { 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 > 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 thrown if id is null 078 * @throws IllegalArgumentException thrown if id.getUniqueId() <= 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 > 0 required. 088 * @param version the specific version number, if required; -1, otherwise 089 * @throws IllegalArgumentException thrown if id is null 090 * @throws IllegalArgumentException thrown if id.getUniqueId() <= 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 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 sb.append("/"); 121 sb.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}