001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005import static org.openstreetmap.josm.tools.I18n.trn; 006 007import java.io.IOException; 008import java.io.InputStream; 009import java.text.MessageFormat; 010import java.util.ArrayList; 011import java.util.Collection; 012import java.util.Collections; 013import java.util.List; 014 015import org.openstreetmap.josm.Main; 016import org.openstreetmap.josm.data.osm.Changeset; 017import org.openstreetmap.josm.data.osm.ChangesetDataSet; 018import org.openstreetmap.josm.data.osm.DataSet; 019import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 020import org.openstreetmap.josm.gui.progress.ProgressMonitor; 021import org.openstreetmap.josm.tools.CheckParameterUtil; 022import org.openstreetmap.josm.tools.XmlParsingException; 023 024/** 025 * Reads the history of an {@link org.openstreetmap.josm.data.osm.OsmPrimitive} from the OSM API server. 026 * 027 */ 028public class OsmServerChangesetReader extends OsmServerReader { 029 030 /** 031 * constructor 032 * 033 */ 034 public OsmServerChangesetReader(){ 035 setDoAuthenticate(false); 036 } 037 038 /** 039 * don't use - not implemented! 040 * 041 */ 042 @Override 043 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException { 044 return null; 045 } 046 047 /** 048 * Queries a list 049 * @param query the query specification. Must not be null. 050 * @param monitor a progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null 051 * @return the list of changesets read from the server 052 * @throws IllegalArgumentException thrown if query is null 053 * @throws OsmTransferException thrown if something goes wrong w 054 */ 055 public List<Changeset> queryChangesets(ChangesetQuery query, ProgressMonitor monitor) throws OsmTransferException { 056 CheckParameterUtil.ensureParameterNotNull(query, "query"); 057 List<Changeset> result = null; 058 if (monitor == null) { 059 monitor = NullProgressMonitor.INSTANCE; 060 } 061 try { 062 monitor.beginTask(tr("Reading changesets...")); 063 StringBuilder sb = new StringBuilder(); 064 sb.append("changesets?").append(query.getQueryString()); 065 try (InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true))) { 066 if (in == null) 067 return null; 068 monitor.indeterminateSubTask(tr("Downloading changesets ...")); 069 result = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true)); 070 } catch (IOException e) { 071 Main.warn(e); 072 } 073 } catch(OsmTransferException e) { 074 throw e; 075 } catch(IllegalDataException e) { 076 throw new OsmTransferException(e); 077 } finally { 078 monitor.finishTask(); 079 } 080 return result; 081 } 082 083 /** 084 * Reads the changeset with id <code>id</code> from the server 085 * 086 * @param id the changeset id. id > 0 required. 087 * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null 088 * @return the changeset read 089 * @throws OsmTransferException thrown if something goes wrong 090 * @throws IllegalArgumentException if id <= 0 091 */ 092 public Changeset readChangeset(long id, ProgressMonitor monitor) throws OsmTransferException { 093 if (id <= 0) 094 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' > 0 expected. Got ''{1}''.", "id", id)); 095 if (monitor == null) { 096 monitor = NullProgressMonitor.INSTANCE; 097 } 098 Changeset result = null; 099 try { 100 monitor.beginTask(tr("Reading changeset {0} ...",id)); 101 StringBuilder sb = new StringBuilder(); 102 sb.append("changeset/").append(id); 103 try (InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true))) { 104 if (in == null) 105 return null; 106 monitor.indeterminateSubTask(tr("Downloading changeset {0} ...", id)); 107 List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true)); 108 if (changesets == null || changesets.isEmpty()) 109 return null; 110 result = changesets.get(0); 111 } catch (IOException e) { 112 Main.warn(e); 113 } 114 } catch(OsmTransferException e) { 115 throw e; 116 } catch(IllegalDataException e) { 117 throw new OsmTransferException(e); 118 } finally { 119 monitor.finishTask(); 120 } 121 return result; 122 } 123 124 /** 125 * Reads the changeset with id <code>id</code> from the server 126 * 127 * @param ids the list of ids. Ignored if null. Only load changesets for ids > 0. 128 * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null 129 * @return the changeset read 130 * @throws OsmTransferException thrown if something goes wrong 131 * @throws IllegalArgumentException if id <= 0 132 */ 133 public List<Changeset> readChangesets(Collection<Integer> ids, ProgressMonitor monitor) throws OsmTransferException { 134 if (ids == null) 135 return Collections.emptyList(); 136 if (monitor == null) { 137 monitor = NullProgressMonitor.INSTANCE; 138 } 139 try { 140 monitor.beginTask(trn("Downloading {0} changeset ...", "Downloading {0} changesets ...",ids.size(),ids.size())); 141 monitor.setTicksCount(ids.size()); 142 List<Changeset> ret = new ArrayList<>(); 143 int i=0; 144 for (int id : ids) { 145 if (id <= 0) { 146 continue; 147 } 148 i++; 149 StringBuilder sb = new StringBuilder(); 150 sb.append("changeset/").append(id); 151 try (InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true))) { 152 if (in == null) 153 return null; 154 monitor.indeterminateSubTask(tr("({0}/{1}) Downloading changeset {2} ...", i, ids.size(), id)); 155 List<Changeset> changesets = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true)); 156 if (changesets == null || changesets.isEmpty()) { 157 continue; 158 } 159 ret.addAll(changesets); 160 } catch (IOException e) { 161 Main.warn(e); 162 } 163 monitor.worked(1); 164 } 165 return ret; 166 } catch(OsmTransferException e) { 167 throw e; 168 } catch(IllegalDataException e) { 169 throw new OsmTransferException(e); 170 } finally { 171 monitor.finishTask(); 172 } 173 } 174 175 /** 176 * Downloads the content of a changeset 177 * 178 * @param id the changeset id. > 0 required. 179 * @param monitor the progress monitor. {@link NullProgressMonitor#INSTANCE} assumed if null. 180 * @return the changeset content 181 * @throws IllegalArgumentException thrown if id <= 0 182 * @throws OsmTransferException thrown if something went wrong 183 */ 184 public ChangesetDataSet downloadChangeset(int id, ProgressMonitor monitor) throws IllegalArgumentException, OsmTransferException { 185 if (id <= 0) 186 throw new IllegalArgumentException(MessageFormat.format("Expected value of type integer > 0 for parameter ''{0}'', got {1}", "id", id)); 187 if (monitor == null) { 188 monitor = NullProgressMonitor.INSTANCE; 189 } 190 ChangesetDataSet result = null; 191 try { 192 monitor.beginTask(tr("Downloading changeset content")); 193 StringBuilder sb = new StringBuilder(); 194 sb.append("changeset/").append(id).append("/download"); 195 try (InputStream in = getInputStream(sb.toString(), monitor.createSubTaskMonitor(1, true))) { 196 if (in == null) 197 return null; 198 monitor.setCustomText(tr("Downloading content for changeset {0} ...", id)); 199 OsmChangesetContentParser parser = new OsmChangesetContentParser(in); 200 result = parser.parse(monitor.createSubTaskMonitor(1, true)); 201 } catch (IOException e) { 202 Main.warn(e); 203 } 204 } catch(XmlParsingException e) { 205 throw new OsmTransferException(e); 206 } finally { 207 monitor.finishTask(); 208 } 209 return result; 210 } 211}