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