001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions.downloadtasks; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.io.IOException; 008import java.util.Collection; 009import java.util.Collections; 010import java.util.HashSet; 011import java.util.Objects; 012import java.util.Set; 013import java.util.stream.Collectors; 014 015import org.openstreetmap.josm.data.osm.Changeset; 016import org.openstreetmap.josm.data.osm.ChangesetCache; 017import org.openstreetmap.josm.gui.ExceptionDialogUtil; 018import org.openstreetmap.josm.gui.MainApplication; 019import org.openstreetmap.josm.io.OsmTransferException; 020import org.xml.sax.SAXException; 021 022/** 023 * This is an asynchronous task for downloading a collection of changests from the OSM server. 024 * 025 * The task only downloads the changeset properties without the changeset content. It 026 * updates the global {@link ChangesetCache}. 027 * @since 2613 028 */ 029public class ChangesetHeaderDownloadTask extends AbstractChangesetDownloadTask { 030 031 class DownloadTask extends RunnableDownloadTask { 032 /** the list of changeset ids to download */ 033 private final Set<Integer> toDownload = new HashSet<>(); 034 /** whether to include discussions or not */ 035 private final boolean includeDiscussion; 036 037 DownloadTask(Component parent, Collection<Integer> ids, boolean includeDiscussion) { 038 super(parent, tr("Download changesets")); 039 this.includeDiscussion = includeDiscussion; 040 for (int id: ids != null ? ids : Collections.<Integer>emptyList()) { 041 if (id <= 0) { 042 continue; 043 } 044 toDownload.add(id); 045 } 046 } 047 048 @Override 049 protected void realRun() throws SAXException, IOException, OsmTransferException { 050 try { 051 downloadedChangesets.addAll(reader.readChangesets(toDownload, includeDiscussion, 052 getProgressMonitor().createSubTaskMonitor(0, false))); 053 } catch (OsmTransferException e) { 054 if (isCanceled()) 055 // ignore exception if canceled 056 return; 057 // remember other exceptions 058 rememberLastException(e); 059 } 060 } 061 062 @Override 063 protected void finish() { 064 rememberDownloadedData(downloadedChangesets); 065 if (isCanceled()) 066 return; 067 if (lastException != null) { 068 ExceptionDialogUtil.explainException(lastException); 069 } 070 updateChangesets(); 071 } 072 } 073 074 /** 075 * Creates the download task for a collection of changeset ids. Uses a {@link org.openstreetmap.josm.gui.PleaseWaitDialog} 076 * whose parent is {@link MainApplication#getMainFrame}. 077 * 078 * Null ids or or ids <= 0 in the id collection are ignored. 079 * 080 * @param ids the collection of ids. Empty collection assumed if null. 081 */ 082 public ChangesetHeaderDownloadTask(Collection<Integer> ids) { 083 this(MainApplication.getMainFrame(), ids, false); 084 } 085 086 /** 087 * Creates the download task for a collection of changeset ids. Uses a {@link org.openstreetmap.josm.gui.PleaseWaitDialog} 088 * whose parent is the parent window of <code>dialogParent</code>. 089 * 090 * Null ids or or ids <= 0 in the id collection are ignored. 091 * 092 * @param dialogParent the parent reference component for the {@link org.openstreetmap.josm.gui.PleaseWaitDialog}. Must not be null. 093 * @param ids the collection of ids. Empty collection assumed if null. 094 * @throws IllegalArgumentException if dialogParent is null 095 */ 096 public ChangesetHeaderDownloadTask(Component dialogParent, Collection<Integer> ids) { 097 this(dialogParent, ids, false); 098 } 099 100 /** 101 * Creates the download task for a collection of changeset ids, with possibility to download changeset discussion. 102 * Uses a {@link org.openstreetmap.josm.gui.PleaseWaitDialog} whose parent is the parent window of <code>dialogParent</code>. 103 * 104 * Null ids or or ids <= 0 in the id collection are ignored. 105 * 106 * @param dialogParent the parent reference component for the {@link org.openstreetmap.josm.gui.PleaseWaitDialog}. Must not be null. 107 * @param ids the collection of ids. Empty collection assumed if null. 108 * @param includeDiscussion determines if discussion comments must be downloaded or not 109 * @throws IllegalArgumentException if dialogParent is null 110 * @since 7704 111 */ 112 public ChangesetHeaderDownloadTask(Component dialogParent, Collection<Integer> ids, boolean includeDiscussion) { 113 setDownloadTask(new DownloadTask(dialogParent, ids, includeDiscussion)); 114 } 115 116 /** 117 * Builds a download task from for a collection of changesets. 118 * 119 * Ignores null values and changesets with {@link Changeset#isNew()} == true. 120 * 121 * @param changesets the collection of changesets. Assumes an empty collection if null. 122 * @return the download task 123 */ 124 public static ChangesetHeaderDownloadTask buildTaskForChangesets(Collection<Changeset> changesets) { 125 return buildTaskForChangesets(MainApplication.getMainFrame(), changesets); 126 } 127 128 /** 129 * Builds a download task from for a collection of changesets. 130 * 131 * Ignores null values and changesets with {@link Changeset#isNew()} == true. 132 * 133 * @param parent the parent component relative to which the {@link org.openstreetmap.josm.gui.PleaseWaitDialog} is displayed. 134 * Must not be null. 135 * @param changesets the collection of changesets. Assumes an empty collection if null. 136 * @return the download task 137 * @throws NullPointerException if parent is null 138 */ 139 public static ChangesetHeaderDownloadTask buildTaskForChangesets(Component parent, Collection<Changeset> changesets) { 140 return new ChangesetHeaderDownloadTask(Objects.requireNonNull(parent, "parent"), 141 changesets == null ? Collections.<Integer>emptySet() : 142 changesets.stream().filter(cs -> cs != null && !cs.isNew()).map(Changeset::getId).collect(Collectors.toSet())); 143 } 144}