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