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