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