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; 008 009import javax.swing.JOptionPane; 010 011import org.openstreetmap.josm.Main; 012import org.openstreetmap.josm.data.osm.UserInfo; 013import org.openstreetmap.josm.gui.JosmUserIdentityManager; 014import org.openstreetmap.josm.gui.util.GuiHelper; 015import org.openstreetmap.josm.io.ChangesetQuery; 016import org.openstreetmap.josm.io.OsmServerUserInfoReader; 017import org.openstreetmap.josm.io.OsmTransferCanceledException; 018import org.openstreetmap.josm.io.OsmTransferException; 019import org.openstreetmap.josm.tools.CheckParameterUtil; 020import org.openstreetmap.josm.tools.ExceptionUtil; 021import org.xml.sax.SAXException; 022 023/** 024 * Asynchronous task to send a changeset query to the OSM API. 025 * @since 2689 026 */ 027public class ChangesetQueryTask extends AbstractChangesetDownloadTask { 028 029 class DownloadTask extends RunnableDownloadTask { 030 /** the changeset query */ 031 private ChangesetQuery query; 032 /** the reader object used to read information about the current user from the API */ 033 private final OsmServerUserInfoReader userInfoReader = new OsmServerUserInfoReader(); 034 035 DownloadTask(Component parent, ChangesetQuery query) { 036 super(parent, tr("Querying and downloading changesets")); 037 this.query = query; 038 } 039 040 /** 041 * Tries to fully identify the current JOSM user 042 * 043 * @throws OsmTransferException if something went wrong 044 */ 045 protected void fullyIdentifyCurrentUser() throws OsmTransferException { 046 getProgressMonitor().indeterminateSubTask(tr("Determine user id for current user...")); 047 048 UserInfo info = userInfoReader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 049 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 050 im.setFullyIdentified(im.getUserName(), info); 051 } 052 053 @Override 054 protected void realRun() throws SAXException, IOException, OsmTransferException { 055 try { 056 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 057 if (query.isRestrictedToPartiallyIdentifiedUser() && im.isCurrentUser(query.getUserName())) { 058 // if we query changesets for the current user, make sure we query against 059 // its user id, not its user name. If necessary, determine the user id first. 060 // 061 if (im.isPartiallyIdentified()) { 062 fullyIdentifyCurrentUser(); 063 } 064 query = query.forUser(JosmUserIdentityManager.getInstance().getUserId()); 065 } 066 if (isCanceled()) 067 return; 068 getProgressMonitor().indeterminateSubTask(tr("Query and download changesets ...")); 069 downloadedChangesets.addAll(reader.queryChangesets(query, getProgressMonitor().createSubTaskMonitor(0, false))); 070 } catch (OsmTransferCanceledException e) { 071 // thrown if user cancel the authentication dialog 072 setCanceled(true); 073 } catch (OsmTransferException e) { 074 if (isCanceled()) 075 return; 076 rememberLastException(e); 077 } 078 } 079 080 @Override 081 protected void finish() { 082 rememberDownloadedData(downloadedChangesets); 083 if (isCanceled()) 084 return; 085 if (lastException != null) { 086 GuiHelper.runInEDTAndWait(new Runnable() { 087 private final Component parent = progressMonitor != null ? progressMonitor.getWindowParent() : null; 088 @Override 089 public void run() { 090 JOptionPane.showMessageDialog( 091 parent != null ? parent : Main.parent, 092 ExceptionUtil.explainException(lastException), 093 tr("Errors during download"), 094 JOptionPane.ERROR_MESSAGE); 095 } 096 }); 097 return; 098 } 099 updateChangesets(); 100 } 101 102 @Override 103 protected void cancel() { 104 super.cancel(); 105 synchronized (this) { 106 if (userInfoReader != null) { 107 userInfoReader.cancel(); 108 } 109 } 110 } 111 } 112 113 /** 114 * Creates the task. 115 * 116 * @param query the query to submit to the OSM server. Must not be null. 117 * @throws IllegalArgumentException if query is null. 118 */ 119 public ChangesetQueryTask(ChangesetQuery query) { 120 this(Main.parent, query); 121 } 122 123 /** 124 * Creates the task. 125 * 126 * @param parent the parent component relative to which the {@link org.openstreetmap.josm.gui.PleaseWaitDialog} is displayed. 127 * Must not be null. 128 * @param query the query to submit to the OSM server. Must not be null. 129 * @throws IllegalArgumentException if query is null. 130 * @throws IllegalArgumentException if parent is null 131 */ 132 public ChangesetQueryTask(Component parent, ChangesetQuery query) { 133 CheckParameterUtil.ensureParameterNotNull(query, "query"); 134 setDownloadTask(new DownloadTask(parent, query)); 135 } 136}