source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentDownloadTask.java@ 2689

Last change on this file since 2689 was 2689, checked in by Gubaer, 14 years ago

new: Changeset Cache Manager for querying, downloading, browsing, and managing changesets within JOSM. See also Changeset Manager and Changeset Query Dialog

File size: 8.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs.changeset;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.io.IOException;
8import java.util.ArrayList;
9import java.util.Collection;
10import java.util.Collections;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Set;
14
15import org.openstreetmap.josm.data.osm.Changeset;
16import org.openstreetmap.josm.data.osm.ChangesetCache;
17import org.openstreetmap.josm.data.osm.ChangesetDataSet;
18import org.openstreetmap.josm.gui.ExceptionDialogUtil;
19import org.openstreetmap.josm.gui.PleaseWaitRunnable;
20import org.openstreetmap.josm.io.OsmServerChangesetReader;
21import org.openstreetmap.josm.io.OsmTransferCancelledException;
22import org.openstreetmap.josm.io.OsmTransferException;
23import org.xml.sax.SAXException;
24
25/**
26 * This is an asynchronous task for downloading the changeset content of a collection of
27 * changesets.
28 *
29 */
30public class ChangesetContentDownloadTask extends PleaseWaitRunnable implements ChangesetDownloadTask{
31
32 /** the list of changeset ids to download */
33 private final List<Integer> toDownload = new ArrayList<Integer>();
34 /** true if the task was canceled */
35 private boolean canceled;
36 /** keeps the last exception thrown in the task, if any */
37 private Exception lastException;
38 /** the reader object used to read changesets from the API */
39 private OsmServerChangesetReader reader;
40 /** the set of downloaded changesets */
41 private Set<Changeset> downloadedChangesets;
42
43 /**
44 * Initialize the task with a collection of changeset ids to download
45 *
46 * @param ids the collection of ids. May be null.
47 */
48 protected void init(Collection<Integer> ids) {
49 if (ids == null) {
50 ids = Collections.emptyList();
51 }
52 for (Integer id: ids) {
53 if (id == null || id <= 0) {
54 continue;
55 }
56 toDownload.add(id);
57 }
58 downloadedChangesets = new HashSet<Changeset>();
59 }
60
61 /**
62 * Creates a download task for a single changeset
63 *
64 * @param changesetId the changeset id. >0 required.
65 * @throws IllegalArgumentException thrown if changesetId <= 0
66 */
67 public ChangesetContentDownloadTask(int changesetId) throws IllegalArgumentException{
68 super(tr("Downloading changeset content"), false /* don't ignore exceptions */);
69 if (changesetId <= 0)
70 throw new IllegalArgumentException(tr("Expected integer value > 0 for parameter ''{0}'', got ''{1}''", "changesetId", changesetId));
71 init(Collections.singleton(changesetId));
72 }
73
74 /**
75 * Creates a download task for a collection of changesets. null values and id <=0 in
76 * the collection are sillently discarded.
77 *
78 * @param changesetIds the changeset ids. Empty collection assumed, if null.
79 */
80 public ChangesetContentDownloadTask(Collection<Integer> changesetIds) {
81 super(tr("Downloading changeset content"), false /* don't ignore exceptions */);
82 init(changesetIds);
83 }
84
85 /**
86 * Creates a download task for a single changeset
87 *
88 * @param parent the parent component for the {@see PleaseWaitDialog}. Must not be null.
89 * @param changesetId the changeset id. >0 required.
90 * @throws IllegalArgumentException thrown if changesetId <= 0
91 * @throws IllegalArgumentException thrown if parent is null
92 */
93 public ChangesetContentDownloadTask(Component parent, int changesetId) throws IllegalArgumentException{
94 super(parent, tr("Downloading changeset content"), false /* don't ignore exceptions */);
95 if (changesetId <= 0)
96 throw new IllegalArgumentException(tr("Expected integer value > 0 for parameter ''{0}'', got ''{1}''", "changesetId", changesetId));
97 init(Collections.singleton(changesetId));
98 }
99
100 /**
101 * Creates a download task for a collection of changesets. null values and id <=0 in
102 * the collection are sillently discarded.
103 *
104 * @param parent the parent component for the {@see PleaseWaitDialog}. Must not be null.
105 * @param changesetIds the changeset ids. Empty collection assumed, if null.
106 * @throws IllegalArgumentException thrown if parent is null
107 */
108 public ChangesetContentDownloadTask(Component parent, Collection<Integer> changesetIds) throws IllegalArgumentException {
109 super(parent, tr("Downloading changeset content"), false /* don't ignore exceptions */);
110 init(changesetIds);
111 }
112
113 /**
114 * Replies true if the local {@see ChangesetCache} already includes the changeset with
115 * id <code>changesetId</code>.
116 *
117 * @param changsetId the changeset id
118 * @return true if the local {@see ChangesetCache} already includes the changeset with
119 * id <code>changesetId</code>
120 */
121 protected boolean isAvailableLocally(int changsetId) {
122 return ChangesetCache.getInstance().get(changsetId) != null;
123 }
124
125 /**
126 * Downloads the changeset with id <code>changesetId</code> (only "header"
127 * information, no content)
128 *
129 * @param changesetId the changeset id
130 * @throws OsmTransferException thrown if something went wrong
131 */
132 protected void downloadChangeset(int changesetId) throws OsmTransferException {
133 synchronized(this) {
134 reader = new OsmServerChangesetReader();
135 }
136 Changeset cs = reader.readChangeset(changesetId, getProgressMonitor().createSubTaskMonitor(0, false));
137 synchronized(this) {
138 reader = null;
139 }
140 ChangesetCache.getInstance().update(cs);
141 }
142
143 @Override
144 protected void cancel() {
145 canceled = true;
146 synchronized (this) {
147 if (reader != null) {
148 reader.cancel();
149 }
150 }
151 }
152
153 @Override
154 protected void finish() {
155 if (canceled) return;
156 if (lastException != null) {
157 ExceptionDialogUtil.explainException(lastException);
158 }
159 }
160
161 @Override
162 protected void realRun() throws SAXException, IOException, OsmTransferException {
163 try {
164 getProgressMonitor().setTicksCount(toDownload.size());
165 int i=0;
166 for (int id: toDownload) {
167 i++;
168 if (!isAvailableLocally(id)) {
169 getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading changeset {2}...", i, toDownload.size(), id));
170 downloadChangeset(id);
171 }
172 if (canceled) return;
173 synchronized(this) {
174 reader = new OsmServerChangesetReader();
175 }
176 getProgressMonitor().setCustomText(tr("({0}/{1}) Downloading content for changeset {2}...", i, toDownload.size(), id));
177 ChangesetDataSet ds = reader.downloadChangeset(id, getProgressMonitor().createSubTaskMonitor(0, false));
178 synchronized(this) {
179 reader = null;
180 }
181 Changeset cs = ChangesetCache.getInstance().get(id);
182 cs.setContent(ds);
183 ChangesetCache.getInstance().update(cs);
184 downloadedChangesets.add(cs);
185 getProgressMonitor().worked(1);
186 }
187 } catch(OsmTransferCancelledException e) {
188 // the download was cancelled by the user. This exception is caught if the
189 // user canceled the authentication dialog.
190 //
191 canceled = true;
192 return;
193 } catch(OsmTransferException e) {
194 if (canceled)
195 return;
196 lastException = e;
197 } catch(RuntimeException e) {
198 throw e;
199 }
200 }
201
202 /* ------------------------------------------------------------------------------- */
203 /* interface ChangesetDownloadTask */
204 /* ------------------------------------------------------------------------------- */
205 public Set<Changeset> getDownloadedChangesets() {
206 return downloadedChangesets;
207 }
208
209 public boolean isCanceled() {
210 return canceled;
211 }
212
213 public boolean isFailed() {
214 return lastException != null;
215 }
216}
Note: See TracBrowser for help on using the repository browser.