001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.gui.oauth;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.awt.Component;
007    import java.io.IOException;
008    
009    import javax.swing.JOptionPane;
010    
011    import org.openstreetmap.josm.data.oauth.OAuthParameters;
012    import org.openstreetmap.josm.data.oauth.OAuthToken;
013    import org.openstreetmap.josm.gui.HelpAwareOptionPane;
014    import org.openstreetmap.josm.gui.PleaseWaitRunnable;
015    import org.openstreetmap.josm.gui.help.HelpUtil;
016    import org.openstreetmap.josm.io.OsmTransferCanceledException;
017    import org.openstreetmap.josm.io.OsmTransferException;
018    import org.openstreetmap.josm.tools.CheckParameterUtil;
019    import org.xml.sax.SAXException;
020    
021    /**
022     * Asynchronous task for retrieving an Access Token.
023     *
024     */
025    public 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
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    }