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 Main.trace(e); 074 } catch (OsmTransferException e) { 075 if (isCanceled()) 076 return; 077 rememberLastException(e); 078 } 079 } 080 081 @Override 082 protected void finish() { 083 rememberDownloadedData(downloadedChangesets); 084 if (isCanceled()) 085 return; 086 if (lastException != null) { 087 GuiHelper.runInEDTAndWait(new Runnable() { 088 private final Component parent = progressMonitor != null ? progressMonitor.getWindowParent() : null; 089 @Override 090 public void run() { 091 JOptionPane.showMessageDialog( 092 parent != null ? parent : Main.parent, 093 ExceptionUtil.explainException(lastException), 094 tr("Errors during download"), 095 JOptionPane.ERROR_MESSAGE); 096 } 097 }); 098 return; 099 } 100 updateChangesets(); 101 } 102 103 @Override 104 protected void cancel() { 105 super.cancel(); 106 synchronized (this) { 107 if (userInfoReader != null) { 108 userInfoReader.cancel(); 109 } 110 } 111 } 112 } 113 114 /** 115 * Creates the task. 116 * 117 * @param query the query to submit to the OSM server. Must not be null. 118 * @throws IllegalArgumentException if query is null. 119 */ 120 public ChangesetQueryTask(ChangesetQuery query) { 121 this(Main.parent, query); 122 } 123 124 /** 125 * Creates the task. 126 * 127 * @param parent the parent component relative to which the {@link org.openstreetmap.josm.gui.PleaseWaitDialog} is displayed. 128 * Must not be null. 129 * @param query the query to submit to the OSM server. Must not be null. 130 * @throws IllegalArgumentException if query is null. 131 * @throws IllegalArgumentException if parent is null 132 */ 133 public ChangesetQueryTask(Component parent, ChangesetQuery query) { 134 CheckParameterUtil.ensureParameterNotNull(query, "query"); 135 setDownloadTask(new DownloadTask(parent, query)); 136 } 137}