source: josm/trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java@ 8836

Last change on this file since 8836 was 8836, checked in by Don-vip, 9 years ago

fix Checkstyle issues

  • Property svn:eol-style set to native
File size: 13.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.oauth;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.FlowLayout;
10import java.awt.Font;
11import java.awt.GridBagConstraints;
12import java.awt.GridBagLayout;
13import java.awt.Insets;
14import java.awt.event.ActionEvent;
15import java.awt.event.ComponentEvent;
16import java.awt.event.ComponentListener;
17import java.awt.event.ItemEvent;
18import java.awt.event.ItemListener;
19import java.awt.event.KeyEvent;
20import java.awt.event.WindowAdapter;
21import java.awt.event.WindowEvent;
22import java.beans.PropertyChangeEvent;
23import java.beans.PropertyChangeListener;
24
25import javax.swing.AbstractAction;
26import javax.swing.BorderFactory;
27import javax.swing.JComponent;
28import javax.swing.JDialog;
29import javax.swing.JLabel;
30import javax.swing.JOptionPane;
31import javax.swing.JPanel;
32import javax.swing.JScrollPane;
33import javax.swing.KeyStroke;
34import javax.swing.UIManager;
35import javax.swing.event.HyperlinkEvent;
36import javax.swing.event.HyperlinkListener;
37
38import org.openstreetmap.josm.Main;
39import org.openstreetmap.josm.data.CustomConfigurator;
40import org.openstreetmap.josm.data.Preferences;
41import org.openstreetmap.josm.data.oauth.OAuthParameters;
42import org.openstreetmap.josm.data.oauth.OAuthToken;
43import org.openstreetmap.josm.gui.SideButton;
44import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
45import org.openstreetmap.josm.gui.help.HelpUtil;
46import org.openstreetmap.josm.gui.util.GuiHelper;
47import org.openstreetmap.josm.gui.widgets.HtmlPanel;
48import org.openstreetmap.josm.tools.CheckParameterUtil;
49import org.openstreetmap.josm.tools.ImageProvider;
50import org.openstreetmap.josm.tools.OpenBrowser;
51import org.openstreetmap.josm.tools.WindowGeometry;
52
53/**
54 * This wizard walks the user to the necessary steps to retrieve an OAuth Access Token which
55 * allows JOSM to access the OSM API on the users behalf.
56 *
57 */
58public class OAuthAuthorizationWizard extends JDialog {
59 private boolean canceled;
60 private final String apiUrl;
61
62 private AuthorizationProcedureComboBox cbAuthorisationProcedure;
63 private FullyAutomaticAuthorizationUI pnlFullyAutomaticAuthorisationUI;
64 private SemiAutomaticAuthorizationUI pnlSemiAutomaticAuthorisationUI;
65 private ManualAuthorizationUI pnlManualAuthorisationUI;
66 private JScrollPane spAuthorisationProcedureUI;
67
68 /**
69 * Builds the row with the action buttons
70 *
71 * @return panel with buttons
72 */
73 protected JPanel buildButtonRow() {
74 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
75
76 AcceptAccessTokenAction actAcceptAccessToken = new AcceptAccessTokenAction();
77 pnlFullyAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
78 pnlSemiAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
79 pnlManualAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
80
81 pnl.add(new SideButton(actAcceptAccessToken));
82 pnl.add(new SideButton(new CancelAction()));
83 pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"))));
84
85 return pnl;
86 }
87
88 /**
89 * Builds the panel with general information in the header
90 *
91 * @return panel with information display
92 */
93 protected JPanel buildHeaderInfoPanel() {
94 JPanel pnl = new JPanel(new GridBagLayout());
95 pnl.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
96 GridBagConstraints gc = new GridBagConstraints();
97
98 // the oauth logo in the header
99 gc.anchor = GridBagConstraints.NORTHWEST;
100 gc.fill = GridBagConstraints.HORIZONTAL;
101 gc.weightx = 1.0;
102 gc.gridwidth = 2;
103 ImageProvider logoProv = new ImageProvider("oauth", "oauth-logo");
104 JLabel lbl = new JLabel(logoProv.get());
105 lbl.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
106 lbl.setOpaque(true);
107 pnl.add(lbl, gc);
108
109 // OAuth in a nutshell ...
110 gc.gridy = 1;
111 gc.insets = new Insets(5, 0, 0, 5);
112 HtmlPanel pnlMessage = new HtmlPanel();
113 pnlMessage.setText("<html><body>"
114 + tr("With OAuth you grant JOSM the right to upload map data and GPS tracks "
115 + "on your behalf (<a href=\"{0}\">more info...</a>).", "http://oauth.net/")
116 + "</body></html>"
117 );
118 pnlMessage.getEditorPane().addHyperlinkListener(new ExternalBrowserLauncher());
119 pnl.add(pnlMessage, gc);
120
121 // the authorisation procedure
122 gc.gridy = 2;
123 gc.gridwidth = 1;
124 gc.weightx = 0.0;
125 lbl = new JLabel(tr("Please select an authorization procedure: "));
126 lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
127 pnl.add(lbl, gc);
128
129 gc.gridx = 1;
130 gc.gridwidth = 1;
131 gc.weightx = 1.0;
132 pnl.add(cbAuthorisationProcedure = new AuthorizationProcedureComboBox(), gc);
133 cbAuthorisationProcedure.addItemListener(new AuthorisationProcedureChangeListener());
134 lbl.setLabelFor(cbAuthorisationProcedure);
135 return pnl;
136 }
137
138 /**
139 * Refreshes the view of the authorisation panel, depending on the authorisation procedure
140 * currently selected
141 */
142 protected void refreshAuthorisationProcedurePanel() {
143 AuthorizationProcedure procedure = (AuthorizationProcedure) cbAuthorisationProcedure.getSelectedItem();
144 switch(procedure) {
145 case FULLY_AUTOMATIC:
146 spAuthorisationProcedureUI.getViewport().setView(pnlFullyAutomaticAuthorisationUI);
147 pnlFullyAutomaticAuthorisationUI.revalidate();
148 break;
149 case SEMI_AUTOMATIC:
150 spAuthorisationProcedureUI.getViewport().setView(pnlSemiAutomaticAuthorisationUI);
151 pnlSemiAutomaticAuthorisationUI.revalidate();
152 break;
153 case MANUALLY:
154 spAuthorisationProcedureUI.getViewport().setView(pnlManualAuthorisationUI);
155 pnlManualAuthorisationUI.revalidate();
156 break;
157 }
158 validate();
159 repaint();
160 }
161
162 /**
163 * builds the UI
164 */
165 protected final void build() {
166 getContentPane().setLayout(new BorderLayout());
167 getContentPane().add(buildHeaderInfoPanel(), BorderLayout.NORTH);
168
169 setTitle(tr("Get an Access Token for ''{0}''", apiUrl));
170 this.setMinimumSize(new Dimension(420, 400));
171
172 pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI(apiUrl);
173 pnlSemiAutomaticAuthorisationUI = new SemiAutomaticAuthorizationUI(apiUrl);
174 pnlManualAuthorisationUI = new ManualAuthorizationUI(apiUrl);
175
176 spAuthorisationProcedureUI = GuiHelper.embedInVerticalScrollPane(new JPanel());
177 spAuthorisationProcedureUI.getVerticalScrollBar().addComponentListener(
178 new ComponentListener() {
179 @Override
180 public void componentShown(ComponentEvent e) {
181 spAuthorisationProcedureUI.setBorder(UIManager.getBorder("ScrollPane.border"));
182 }
183
184 @Override
185 public void componentHidden(ComponentEvent e) {
186 spAuthorisationProcedureUI.setBorder(null);
187 }
188
189 @Override
190 public void componentResized(ComponentEvent e) {}
191
192 @Override
193 public void componentMoved(ComponentEvent e) {}
194 }
195 );
196 getContentPane().add(spAuthorisationProcedureUI, BorderLayout.CENTER);
197 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
198
199 addWindowListener(new WindowEventHandler());
200 getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
201 getRootPane().getActionMap().put("cancel", new CancelAction());
202
203 refreshAuthorisationProcedurePanel();
204
205 HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"));
206 }
207
208 /**
209 * Creates the wizard.
210 *
211 * @param apiUrl the API URL. Must not be null.
212 * @throws IllegalArgumentException if apiUrl is null
213 */
214 public OAuthAuthorizationWizard(String apiUrl) {
215 this(Main.parent, apiUrl);
216 }
217
218 /**
219 * Creates the wizard.
220 *
221 * @param parent the component relative to which the dialog is displayed
222 * @param apiUrl the API URL. Must not be null.
223 * @throws IllegalArgumentException if apiUrl is null
224 */
225 public OAuthAuthorizationWizard(Component parent, String apiUrl) {
226 super(JOptionPane.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL);
227 CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
228 this.apiUrl = apiUrl;
229 build();
230 }
231
232 /**
233 * Replies true if the dialog was canceled
234 *
235 * @return true if the dialog was canceled
236 */
237 public boolean isCanceled() {
238 return canceled;
239 }
240
241 protected AbstractAuthorizationUI getCurrentAuthorisationUI() {
242 switch((AuthorizationProcedure) cbAuthorisationProcedure.getSelectedItem()) {
243 case FULLY_AUTOMATIC: return pnlFullyAutomaticAuthorisationUI;
244 case MANUALLY: return pnlManualAuthorisationUI;
245 case SEMI_AUTOMATIC: return pnlSemiAutomaticAuthorisationUI;
246 default: return null;
247 }
248 }
249
250 /**
251 * Replies the Access Token entered using the wizard
252 *
253 * @return the access token. May be null if the wizard was canceled.
254 */
255 public OAuthToken getAccessToken() {
256 return getCurrentAuthorisationUI().getAccessToken();
257 }
258
259 /**
260 * Replies the current OAuth parameters.
261 *
262 * @return the current OAuth parameters.
263 */
264 public OAuthParameters getOAuthParameters() {
265 return getCurrentAuthorisationUI().getOAuthParameters();
266 }
267
268 /**
269 * Replies true if the currently selected Access Token shall be saved to
270 * the preferences.
271 *
272 * @return true if the currently selected Access Token shall be saved to
273 * the preferences
274 */
275 public boolean isSaveAccessTokenToPreferences() {
276 return getCurrentAuthorisationUI().isSaveAccessTokenToPreferences();
277 }
278
279 /**
280 * Initializes the dialog with values from the preferences
281 *
282 */
283 public void initFromPreferences() {
284 // Copy current JOSM preferences to update API url with the one used in this wizard
285 Preferences copyPref = CustomConfigurator.clonePreferences(Main.pref);
286 copyPref.put("osm-server.url", apiUrl);
287 pnlFullyAutomaticAuthorisationUI.initFromPreferences(copyPref);
288 pnlSemiAutomaticAuthorisationUI.initFromPreferences(copyPref);
289 pnlManualAuthorisationUI.initFromPreferences(copyPref);
290 }
291
292 @Override
293 public void setVisible(boolean visible) {
294 if (visible) {
295 new WindowGeometry(
296 getClass().getName() + ".geometry",
297 WindowGeometry.centerInWindow(
298 Main.parent,
299 new Dimension(450, 540)
300 )
301 ).applySafe(this);
302 initFromPreferences();
303 } else if (isShowing()) { // Avoid IllegalComponentStateException like in #8775
304 new WindowGeometry(this).remember(getClass().getName() + ".geometry");
305 }
306 super.setVisible(visible);
307 }
308
309 protected void setCanceled(boolean canceled) {
310 this.canceled = canceled;
311 }
312
313 class AuthorisationProcedureChangeListener implements ItemListener {
314 @Override
315 public void itemStateChanged(ItemEvent arg0) {
316 refreshAuthorisationProcedurePanel();
317 }
318 }
319
320 class CancelAction extends AbstractAction {
321
322 /**
323 * Constructs a new {@code CancelAction}.
324 */
325 CancelAction() {
326 putValue(NAME, tr("Cancel"));
327 putValue(SMALL_ICON, ImageProvider.get("cancel"));
328 putValue(SHORT_DESCRIPTION, tr("Close the dialog and cancel authorization"));
329 }
330
331 public void cancel() {
332 setCanceled(true);
333 setVisible(false);
334 }
335
336 @Override
337 public void actionPerformed(ActionEvent evt) {
338 cancel();
339 }
340 }
341
342 class AcceptAccessTokenAction extends AbstractAction implements PropertyChangeListener {
343
344 /**
345 * Constructs a new {@code AcceptAccessTokenAction}.
346 */
347 AcceptAccessTokenAction() {
348 putValue(NAME, tr("Accept Access Token"));
349 putValue(SMALL_ICON, ImageProvider.get("ok"));
350 putValue(SHORT_DESCRIPTION, tr("Close the dialog and accept the Access Token"));
351 updateEnabledState(null);
352 }
353
354 @Override
355 public void actionPerformed(ActionEvent evt) {
356 setCanceled(false);
357 setVisible(false);
358 }
359
360 public final void updateEnabledState(OAuthToken token) {
361 setEnabled(token != null);
362 }
363
364 @Override
365 public void propertyChange(PropertyChangeEvent evt) {
366 if (!evt.getPropertyName().equals(AbstractAuthorizationUI.ACCESS_TOKEN_PROP))
367 return;
368 updateEnabledState((OAuthToken) evt.getNewValue());
369 }
370 }
371
372 class WindowEventHandler extends WindowAdapter {
373 @Override
374 public void windowClosing(WindowEvent e) {
375 new CancelAction().cancel();
376 }
377 }
378
379 static class ExternalBrowserLauncher implements HyperlinkListener {
380 @Override
381 public void hyperlinkUpdate(HyperlinkEvent e) {
382 if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
383 OpenBrowser.displayUrl(e.getDescription());
384 }
385 }
386 }
387}
Note: See TracBrowser for help on using the repository browser.