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