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