001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.oauth; 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.data.oauth.OAuthParameters; 012import org.openstreetmap.josm.data.oauth.OAuthToken; 013import org.openstreetmap.josm.gui.HelpAwareOptionPane; 014import org.openstreetmap.josm.gui.PleaseWaitRunnable; 015import org.openstreetmap.josm.gui.help.HelpUtil; 016import org.openstreetmap.josm.gui.util.GuiHelper; 017import org.openstreetmap.josm.io.OsmTransferCanceledException; 018import org.openstreetmap.josm.io.OsmTransferException; 019import org.openstreetmap.josm.tools.CheckParameterUtil; 020import org.openstreetmap.josm.tools.Logging; 021import org.xml.sax.SAXException; 022 023/** 024 * Asynchronous task for retrieving an Access Token. 025 * 026 */ 027public class RetrieveAccessTokenTask extends PleaseWaitRunnable { 028 029 private boolean canceled; 030 private OAuthToken accessToken; 031 private final OAuthParameters parameters; 032 private OsmOAuthAuthorizationClient client; 033 private final OAuthToken requestToken; 034 private final Component parent; 035 036 /** 037 * Creates the task 038 * 039 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog 040 * is displayed 041 * @param parameters the OAuth parameters. Must not be null. 042 * @param requestToken the request token for which an Access Token is retrieved. Must not be null. 043 * @throws IllegalArgumentException if parameters is null. 044 * @throws IllegalArgumentException if requestToken is null. 045 */ 046 public RetrieveAccessTokenTask(Component parent, OAuthParameters parameters, OAuthToken requestToken) { 047 super(parent, tr("Retrieving OAuth Access Token..."), false /* don't ignore exceptions */); 048 CheckParameterUtil.ensureParameterNotNull(parameters, "parameters"); 049 CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken"); 050 this.parameters = parameters; 051 this.requestToken = requestToken; 052 this.parent = parent; 053 } 054 055 @Override 056 protected void cancel() { 057 canceled = true; 058 synchronized (this) { 059 if (client != null) { 060 client.cancel(); 061 } 062 } 063 } 064 065 @Override 066 protected void finish() { /* not used in this task */} 067 068 protected void alertRetrievingAccessTokenFailed() { 069 HelpAwareOptionPane.showOptionDialog( 070 parent, 071 tr( 072 "<html>Retrieving an OAuth Access Token from ''{0}'' failed.</html>", 073 parameters.getAccessTokenUrl() 074 ), 075 tr("Request Failed"), 076 JOptionPane.ERROR_MESSAGE, 077 HelpUtil.ht("/OAuth#NotAuthorizedException") 078 ); 079 } 080 081 @Override 082 protected void realRun() throws SAXException, IOException, OsmTransferException { 083 try { 084 synchronized (this) { 085 client = new OsmOAuthAuthorizationClient(parameters, requestToken); 086 } 087 accessToken = client.getAccessToken(getProgressMonitor().createSubTaskMonitor(0, false)); 088 } catch (OsmTransferCanceledException e) { 089 Logging.trace(e); 090 } catch (final OsmOAuthAuthorizationException e) { 091 Logging.error(e); 092 GuiHelper.runInEDT(this::alertRetrievingAccessTokenFailed); 093 accessToken = null; 094 } finally { 095 synchronized (this) { 096 client = null; 097 } 098 } 099 } 100 101 /** 102 * Replies true if the task was canceled. 103 * 104 * @return {@code true} if user aborted operation 105 */ 106 public boolean isCanceled() { 107 return canceled; 108 } 109 110 /** 111 * Replies the retrieved Access Token. null, if something went wrong. 112 * 113 * @return the retrieved Access Token 114 */ 115 public OAuthToken getAccessToken() { 116 return accessToken; 117 } 118}