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 107 * null 108 * @return the downloaded data 109 * @throws OsmTransferException 110 */ 111 @Override 112 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException { 113 if (progressMonitor == null) { 114 progressMonitor = NullProgressMonitor.INSTANCE; 115 } 116 progressMonitor.beginTask("", 1); 117 try { 118 progressMonitor.indeterminateSubTask(tr("Downloading OSM data...")); 119 StringBuilder sb = new StringBuilder(); 120 sb.append(id.getType().getAPIName()); 121 sb.append("/"); 122 sb.append(id.getUniqueId()); 123 if (full && ! id.getType().equals(OsmPrimitiveType.NODE)) { 124 sb.append("/full"); 125 } else if (version > 0) { 126 sb.append("/").append(version); 127 } 128 129 try (InputStream in = getInputStream(sb.toString(), progressMonitor.createSubTaskMonitor(1, true))) { 130 if (in == null) 131 return null; 132 return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 133 } 134 } catch(OsmTransferException e) { 135 if (cancel) return null; 136 throw e; 137 } catch (Exception e) { 138 if (cancel) return null; 139 throw new OsmTransferException(e); 140 } finally { 141 progressMonitor.finishTask(); 142 activeConnection = null; 143 } 144 } 145}