001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui.io; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.Component; 007 import java.io.IOException; 008 import java.util.List; 009 010 import javax.swing.JOptionPane; 011 import javax.swing.SwingUtilities; 012 013 import org.openstreetmap.josm.Main; 014 import org.openstreetmap.josm.data.osm.Changeset; 015 import org.openstreetmap.josm.data.osm.ChangesetCache; 016 import org.openstreetmap.josm.data.osm.UserInfo; 017 import org.openstreetmap.josm.gui.ExceptionDialogUtil; 018 import org.openstreetmap.josm.gui.JosmUserIdentityManager; 019 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 020 import org.openstreetmap.josm.io.ChangesetQuery; 021 import org.openstreetmap.josm.io.OsmServerChangesetReader; 022 import org.openstreetmap.josm.io.OsmServerUserInfoReader; 023 import org.openstreetmap.josm.io.OsmTransferException; 024 import org.xml.sax.SAXException; 025 026 /** 027 * This is a task for downloading the open changesets of the current user 028 * from the OSM server. 029 */ 030 public class DownloadOpenChangesetsTask extends PleaseWaitRunnable { 031 032 private boolean canceled; 033 private OsmServerChangesetReader reader; 034 private List<Changeset> changesets; 035 private Exception lastException; 036 private Component parent; 037 038 /** 039 * 040 * @param model provides the user id of the current user and accepts the changesets 041 * after download 042 */ 043 public DownloadOpenChangesetsTask(Component parent) { 044 super(parent, tr("Downloading open changesets ..."), false /* don't ignore exceptions */); 045 this.parent = parent; 046 } 047 048 @Override 049 protected void cancel() { 050 this.canceled = true; 051 synchronized(this) { 052 if (reader != null) { 053 reader.cancel(); 054 } 055 } 056 } 057 058 @Override 059 protected void finish() { 060 if (JosmUserIdentityManager.getInstance().isAnonymous()) { 061 JOptionPane.showMessageDialog( 062 JOptionPane.getFrameForComponent(parent), 063 "<html>" + tr("Could not retrieve the list of your open changesets because<br>" 064 + "JOSM does not know your identity.<br>" 065 + "You have either chosen to work anonymously or you are not entitled<br>" 066 + "to know the identity of the user on whose behalf you are working.") 067 + "</html>", 068 tr("Missing user identity"), 069 JOptionPane.ERROR_MESSAGE 070 ); 071 return; 072 } 073 if (canceled)return; 074 if (lastException != null) { 075 ExceptionDialogUtil.explainException(lastException); 076 return; 077 } 078 if (changesets.isEmpty()) { 079 JOptionPane.showMessageDialog( 080 Main.parent, 081 tr("There are no open changesets"), 082 tr("No open changesets"), 083 JOptionPane.INFORMATION_MESSAGE 084 ); 085 return; 086 } 087 SwingUtilities.invokeLater( 088 new Runnable() { 089 public void run() { 090 ChangesetCache.getInstance().update(changesets); 091 } 092 } 093 ); 094 } 095 096 /** 097 * Refreshes the user info from the server. This is necessary if we don't know 098 * the users id yet. 099 * 100 */ 101 protected void refreshUserIdentity(){ 102 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 103 try { 104 OsmServerUserInfoReader reader = new OsmServerUserInfoReader(); 105 UserInfo info = reader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 106 im.setFullyIdentified(info.getDisplayName(), info); 107 } catch(OsmTransferException e) { 108 // retrieving the user info can fail if the current user is not authorised to 109 // retrieve it, i.e. if he is working with an OAuth Access Token which doesn't 110 // have the respective privileges or if he didn't or he can't authenticate with 111 // a username/password-pair. 112 // 113 // Downgrade your knowlege about its identity if we've assumed that he was fully 114 // identified. Otherwise, if he is anonymous or partially identified, keep our level 115 // of knowlege. 116 // 117 if (im.isFullyIdentified()) { 118 im.setPartiallyIdentified(im.getUserName()); 119 } 120 System.err.println(tr("Warning: Failed to retrieve user infos for the current JOSM user. Exception was: {0}", e.toString())); 121 } 122 } 123 124 @Override 125 protected void realRun() throws SAXException, IOException, OsmTransferException { 126 try { 127 JosmUserIdentityManager im = JosmUserIdentityManager.getInstance(); 128 if (im.isAnonymous()) { 129 refreshUserIdentity(); 130 } else if (im.isFullyIdentified()){ 131 // do nothing 132 } else if (im.isPartiallyIdentified()) { 133 refreshUserIdentity(); 134 } 135 if (canceled)return; 136 synchronized(this) { 137 reader = new OsmServerChangesetReader(); 138 } 139 ChangesetQuery query = new ChangesetQuery().beingOpen(true); 140 if (im.isAnonymous()) 141 // we still don't know anything about the current user. Can't retrieve 142 // its changesets 143 return; 144 else if (im.isFullyIdentified()) { 145 query = query.forUser(im.getUserId()); 146 } else { 147 // we only know the users name, not its id. Nevermind, try to read 148 // its open changesets anyway. 149 // 150 query = query.forUser(im.getUserName()); 151 } 152 changesets = reader.queryChangesets( 153 query, 154 getProgressMonitor().createSubTaskMonitor(1, false /* not internal */) 155 ); 156 } catch(Exception e) { 157 if (canceled) 158 return; 159 lastException = e; 160 } 161 } 162 163 public boolean isCanceled() { 164 return canceled; 165 } 166 }