source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreferencesPanel.java@ 6971

Last change on this file since 6971 was 6971, checked in by akks, 10 years ago

Add proxy.exceptions advanced parameter (localhost and 127.0.0.1 by default)

  • Property svn:eol-style set to native
File size: 15.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.server;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trc;
6
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.GridBagConstraints;
10import java.awt.GridBagLayout;
11import java.awt.Insets;
12import java.awt.event.ItemEvent;
13import java.awt.event.ItemListener;
14import java.net.Authenticator.RequestorType;
15import java.net.PasswordAuthentication;
16import java.net.ProxySelector;
17import java.util.HashMap;
18import java.util.Map;
19
20import javax.swing.BorderFactory;
21import javax.swing.ButtonGroup;
22import javax.swing.JLabel;
23import javax.swing.JPanel;
24import javax.swing.JRadioButton;
25
26import org.openstreetmap.josm.Main;
27import org.openstreetmap.josm.gui.help.HelpUtil;
28import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
29import org.openstreetmap.josm.gui.widgets.JosmPasswordField;
30import org.openstreetmap.josm.gui.widgets.JosmTextField;
31import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
32import org.openstreetmap.josm.io.DefaultProxySelector;
33import org.openstreetmap.josm.io.auth.CredentialsAgent;
34import org.openstreetmap.josm.io.auth.CredentialsAgentException;
35import org.openstreetmap.josm.io.auth.CredentialsManager;
36import org.openstreetmap.josm.tools.GBC;
37
38/**
39 * Component allowing input of proxy settings.
40 */
41public class ProxyPreferencesPanel extends VerticallyScrollablePanel {
42
43 /**
44 * The proxy policy is how JOSM will use proxy information.
45 */
46 public enum ProxyPolicy {
47 /** No proxy: JOSM will access Internet resources directly */
48 NO_PROXY("no-proxy"),
49 /** Use system settings: JOSM will use system proxy settings */
50 USE_SYSTEM_SETTINGS("use-system-settings"),
51 /** Use HTTP proxy: JOSM will use the given HTTP proxy, configured manually */
52 USE_HTTP_PROXY("use-http-proxy"),
53 /** Use HTTP proxy: JOSM will use the given SOCKS proxy */
54 USE_SOCKS_PROXY("use-socks-proxy");
55
56 private String policyName;
57 ProxyPolicy(String policyName) {
58 this.policyName = policyName;
59 }
60
61 /**
62 * Replies the policy name, to be stored in proxy preferences.
63 * @return the policy unique name
64 */
65 public String getName() {
66 return policyName;
67 }
68
69 /**
70 * Retrieves a proxy policy from its name found in preferences.
71 * @param policyName The policy name
72 * @return The proxy policy matching the given name, or {@code null}
73 */
74 public static ProxyPolicy fromName(String policyName) {
75 if (policyName == null) return null;
76 policyName = policyName.trim().toLowerCase();
77 for(ProxyPolicy pp: values()) {
78 if (pp.getName().equals(policyName))
79 return pp;
80 }
81 return null;
82 }
83 }
84
85 /** Property key for proxy policy */
86 public static final String PROXY_POLICY = "proxy.policy";
87 /** Property key for HTTP proxy host */
88 public static final String PROXY_HTTP_HOST = "proxy.http.host";
89 /** Property key for HTTP proxy port */
90 public static final String PROXY_HTTP_PORT = "proxy.http.port";
91 /** Property key for SOCKS proxy host */
92 public static final String PROXY_SOCKS_HOST = "proxy.socks.host";
93 /** Property key for SOCKS proxy port */
94 public static final String PROXY_SOCKS_PORT = "proxy.socks.port";
95 /** Property key for proxy username */
96 public static final String PROXY_USER = "proxy.user";
97 /** Property key for proxy password */
98 public static final String PROXY_PASS = "proxy.pass";
99 /** Property key for proxy exceptions list */
100 public static final String PROXY_EXCEPTIONS = "proxy.exceptions";
101
102 private Map<ProxyPolicy, JRadioButton> rbProxyPolicy;
103 private JosmTextField tfProxyHttpHost;
104 private JosmTextField tfProxyHttpPort;
105 private JosmTextField tfProxySocksHost;
106 private JosmTextField tfProxySocksPort;
107 private JosmTextField tfProxyHttpUser;
108 private JosmPasswordField tfProxyHttpPassword;
109
110 private JPanel pnlHttpProxyConfigurationPanel;
111 private JPanel pnlSocksProxyConfigurationPanel;
112
113 /**
114 * Builds the panel for the HTTP proxy configuration
115 *
116 * @return panel with HTTP proxy configuration
117 */
118 protected final JPanel buildHttpProxyConfigurationPanel() {
119 JPanel pnl = new JPanel(new GridBagLayout()) {
120 @Override
121 public Dimension getMinimumSize() {
122 return getPreferredSize();
123 }
124 };
125 GridBagConstraints gc = new GridBagConstraints();
126
127 gc.anchor = GridBagConstraints.WEST;
128 gc.insets = new Insets(5,5,0,0);
129 gc.fill = GridBagConstraints.HORIZONTAL;
130 gc.weightx = 0.0;
131 pnl.add(new JLabel(tr("Host:")), gc);
132
133 gc.gridx = 1;
134 gc.weightx = 1.0;
135 pnl.add(tfProxyHttpHost = new JosmTextField(),gc);
136
137 gc.gridy = 1;
138 gc.gridx = 0;
139 gc.fill = GridBagConstraints.NONE;
140 gc.weightx = 0.0;
141 pnl.add(new JLabel(trc("server", "Port:")), gc);
142
143 gc.gridx = 1;
144 gc.weightx = 1.0;
145 pnl.add(tfProxyHttpPort = new JosmTextField(5),gc);
146 tfProxyHttpPort.setMinimumSize(tfProxyHttpPort.getPreferredSize());
147
148 gc.gridy = 2;
149 gc.gridx = 0;
150 gc.gridwidth = 2;
151 gc.fill = GridBagConstraints.HORIZONTAL;
152 gc.weightx = 1.0;
153 pnl.add(new JMultilineLabel(tr("Please enter a username and a password if your proxy requires authentication.")), gc);
154
155 gc.gridy = 3;
156 gc.gridx = 0;
157 gc.gridwidth = 1;
158 gc.fill = GridBagConstraints.NONE;
159 gc.weightx = 0.0;
160 pnl.add(new JLabel(tr("User:")), gc);
161
162 gc.gridy = 3;
163 gc.gridx = 1;
164 gc.weightx = 1.0;
165 pnl.add(tfProxyHttpUser = new JosmTextField(20),gc);
166 tfProxyHttpUser.setMinimumSize(tfProxyHttpUser.getPreferredSize());
167
168 gc.gridy = 4;
169 gc.gridx = 0;
170 gc.weightx = 0.0;
171 pnl.add(new JLabel(tr("Password:")), gc);
172
173 gc.gridx = 1;
174 gc.weightx = 1.0;
175 pnl.add(tfProxyHttpPassword = new JosmPasswordField(20),gc);
176 tfProxyHttpPassword.setMinimumSize(tfProxyHttpPassword.getPreferredSize());
177
178 // add an extra spacer, otherwise the layout is broken
179 gc.gridy = 5;
180 gc.gridx = 0;
181 gc.gridwidth = 2;
182 gc.fill = GridBagConstraints.BOTH;
183 gc.weightx = 1.0;
184 gc.weighty = 1.0;
185 pnl.add(new JPanel(), gc);
186 return pnl;
187 }
188
189 /**
190 * Builds the panel for the SOCKS proxy configuration
191 *
192 * @return panel with SOCKS proxy configuration
193 */
194 protected final JPanel buildSocksProxyConfigurationPanel() {
195 JPanel pnl = new JPanel(new GridBagLayout()) {
196 @Override
197 public Dimension getMinimumSize() {
198 return getPreferredSize();
199 }
200 };
201 GridBagConstraints gc = new GridBagConstraints();
202 gc.anchor = GridBagConstraints.WEST;
203 gc.insets = new Insets(5,5,0,0);
204 gc.fill = GridBagConstraints.HORIZONTAL;
205 gc.weightx = 0.0;
206 pnl.add(new JLabel(tr("Host:")), gc);
207
208 gc.gridx = 1;
209 gc.weightx = 1.0;
210 pnl.add(tfProxySocksHost = new JosmTextField(20),gc);
211
212 gc.gridy = 1;
213 gc.gridx = 0;
214 gc.weightx = 0.0;
215 gc.fill = GridBagConstraints.NONE;
216 pnl.add(new JLabel(trc("server", "Port:")), gc);
217
218 gc.gridx = 1;
219 gc.weightx = 1.0;
220 pnl.add(tfProxySocksPort = new JosmTextField(5), gc);
221 tfProxySocksPort.setMinimumSize(tfProxySocksPort.getPreferredSize());
222
223 // add an extra spacer, otherwise the layout is broken
224 gc.gridy = 2;
225 gc.gridx = 0;
226 gc.gridwidth = 2;
227 gc.fill = GridBagConstraints.BOTH;
228 gc.weightx = 1.0;
229 gc.weighty = 1.0;
230 pnl.add(new JPanel(), gc);
231 return pnl;
232 }
233
234 protected final JPanel buildProxySettingsPanel() {
235 JPanel pnl = new JPanel(new GridBagLayout());
236 GridBagConstraints gc = new GridBagConstraints();
237
238 ButtonGroup bgProxyPolicy = new ButtonGroup();
239 rbProxyPolicy = new HashMap<ProxyPolicy, JRadioButton>();
240 ProxyPolicyChangeListener policyChangeListener = new ProxyPolicyChangeListener();
241 for (ProxyPolicy pp: ProxyPolicy.values()) {
242 rbProxyPolicy.put(pp, new JRadioButton());
243 bgProxyPolicy.add(rbProxyPolicy.get(pp));
244 rbProxyPolicy.get(pp).addItemListener(policyChangeListener);
245 }
246
247 // radio button "No proxy"
248 gc.gridx = 0;
249 gc.gridy = 0;
250 gc.fill = GridBagConstraints.HORIZONTAL;
251 gc.anchor = GridBagConstraints.NORTHWEST;
252 gc.weightx = 0.0;
253 pnl.add(rbProxyPolicy.get(ProxyPolicy.NO_PROXY),gc);
254
255 gc.gridx = 1;
256 gc.weightx = 1.0;
257 pnl.add(new JLabel(tr("No proxy")), gc);
258
259 // radio button "System settings"
260 gc.gridx = 0;
261 gc.gridy = 1;
262 gc.weightx = 0.0;
263 pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_SYSTEM_SETTINGS),gc);
264
265 gc.gridx = 1;
266 gc.weightx = 1.0;
267 String msg;
268 if (DefaultProxySelector.willJvmRetrieveSystemProxies()) {
269 msg = tr("Use standard system settings");
270 } else {
271 msg = tr("Use standard system settings (disabled. Start JOSM with <tt>-Djava.net.useSystemProxies=true</tt> to enable)");
272 }
273 pnl.add(new JMultilineLabel("<html>" + msg + "</html>"), gc);
274
275 // radio button http proxy
276 gc.gridx = 0;
277 gc.gridy = 2;
278 gc.weightx = 0.0;
279 pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY),gc);
280
281 gc.gridx = 1;
282 gc.weightx = 1.0;
283 pnl.add(new JLabel(tr("Manually configure a HTTP proxy")),gc);
284
285 // the panel with the http proxy configuration parameters
286 gc.gridx = 1;
287 gc.gridy = 3;
288 gc.fill = GridBagConstraints.HORIZONTAL;
289 gc.weightx = 1.0;
290 gc.weighty = 0.0;
291 pnl.add(pnlHttpProxyConfigurationPanel = buildHttpProxyConfigurationPanel(),gc);
292
293 // radio button SOCKS proxy
294 gc.gridx = 0;
295 gc.gridy = 4;
296 gc.weightx = 0.0;
297 pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY),gc);
298
299 gc.gridx = 1;
300 gc.weightx = 1.0;
301 pnl.add(new JLabel(tr("Use a SOCKS proxy")),gc);
302
303 // the panel with the SOCKS configuration parameters
304 gc.gridx = 1;
305 gc.gridy = 5;
306 gc.fill = GridBagConstraints.BOTH;
307 gc.anchor = GridBagConstraints.WEST;
308 gc.weightx = 1.0;
309 gc.weighty = 0.0;
310 pnl.add(pnlSocksProxyConfigurationPanel = buildSocksProxyConfigurationPanel(),gc);
311
312 return pnl;
313 }
314
315 /**
316 * Initializes the panel with the values from the preferences
317 */
318 public final void initFromPreferences() {
319 String policy = Main.pref.get(PROXY_POLICY, null);
320 ProxyPolicy pp = ProxyPolicy.fromName(policy);
321 if (pp == null) {
322 pp = ProxyPolicy.NO_PROXY;
323 }
324 rbProxyPolicy.get(pp).setSelected(true);
325 String value = Main.pref.get("proxy.host", null);
326 if (value != null) {
327 // legacy support
328 tfProxyHttpHost.setText(value);
329 Main.pref.put("proxy.host", null);
330 } else {
331 tfProxyHttpHost.setText(Main.pref.get(PROXY_HTTP_HOST, ""));
332 }
333 value = Main.pref.get("proxy.port", null);
334 if (value != null) {
335 // legacy support
336 tfProxyHttpPort.setText(value);
337 Main.pref.put("proxy.port", null);
338 } else {
339 tfProxyHttpPort.setText(Main.pref.get(PROXY_HTTP_PORT, ""));
340 }
341 tfProxySocksHost.setText(Main.pref.get(PROXY_SOCKS_HOST, ""));
342 tfProxySocksPort.setText(Main.pref.get(PROXY_SOCKS_PORT, ""));
343
344 if (pp.equals(ProxyPolicy.USE_SYSTEM_SETTINGS) && ! DefaultProxySelector.willJvmRetrieveSystemProxies()) {
345 Main.warn(tr("JOSM is configured to use proxies from the system setting, but the JVM is not configured to retrieve them. Resetting preferences to ''No proxy''"));
346 pp = ProxyPolicy.NO_PROXY;
347 rbProxyPolicy.get(pp).setSelected(true);
348 }
349
350 // save the proxy user and the proxy password to a credentials store managed by
351 // the credentials manager
352 CredentialsAgent cm = CredentialsManager.getInstance();
353 try {
354 PasswordAuthentication pa = cm.lookup(RequestorType.PROXY, tfProxyHttpHost.getText());
355 if (pa == null) {
356 tfProxyHttpUser.setText("");
357 tfProxyHttpPassword.setText("");
358 } else {
359 tfProxyHttpUser.setText(pa.getUserName() == null ? "" : pa.getUserName());
360 tfProxyHttpPassword.setText(pa.getPassword() == null ? "" : String.valueOf(pa.getPassword()));
361 }
362 } catch(CredentialsAgentException e) {
363 Main.error(e);
364 tfProxyHttpUser.setText("");
365 tfProxyHttpPassword.setText("");
366 }
367 }
368
369 protected final void updateEnabledState() {
370 boolean isHttpProxy = rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY).isSelected();
371 for (Component c: pnlHttpProxyConfigurationPanel.getComponents()) {
372 c.setEnabled(isHttpProxy);
373 }
374
375 boolean isSocksProxy = rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY).isSelected();
376 for (Component c: pnlSocksProxyConfigurationPanel.getComponents()) {
377 c.setEnabled(isSocksProxy);
378 }
379
380 rbProxyPolicy.get(ProxyPolicy.USE_SYSTEM_SETTINGS).setEnabled(DefaultProxySelector.willJvmRetrieveSystemProxies());
381 }
382
383 class ProxyPolicyChangeListener implements ItemListener {
384 @Override
385 public void itemStateChanged(ItemEvent arg0) {
386 updateEnabledState();
387 }
388 }
389
390 /**
391 * Constructs a new {@code ProxyPreferencesPanel}.
392 */
393 public ProxyPreferencesPanel() {
394 setLayout(new GridBagLayout());
395 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
396 add(buildProxySettingsPanel(), GBC.eop().anchor(GridBagConstraints.NORTHWEST).fill(GridBagConstraints.BOTH));
397
398 initFromPreferences();
399 updateEnabledState();
400
401 HelpUtil.setHelpContext(this, HelpUtil.ht("/Preferences/Connection#ProxySettings"));
402 }
403
404 /**
405 * Saves the current values to the preferences
406 */
407 public void saveToPreferences() {
408 ProxyPolicy policy = null;
409 for (ProxyPolicy pp: ProxyPolicy.values()) {
410 if (rbProxyPolicy.get(pp).isSelected()) {
411 policy = pp;
412 break;
413 }
414 }
415 if (policy == null) {
416 policy = ProxyPolicy.NO_PROXY;
417 }
418 Main.pref.put(PROXY_POLICY, policy.getName());
419 Main.pref.put(PROXY_HTTP_HOST, tfProxyHttpHost.getText());
420 Main.pref.put(PROXY_HTTP_PORT, tfProxyHttpPort.getText());
421 Main.pref.put(PROXY_SOCKS_HOST, tfProxySocksHost.getText());
422 Main.pref.put(PROXY_SOCKS_PORT, tfProxySocksPort.getText());
423
424 // update the proxy selector
425 ProxySelector selector = ProxySelector.getDefault();
426 if (selector instanceof DefaultProxySelector) {
427 ((DefaultProxySelector)selector).initFromPreferences();
428 }
429
430 CredentialsAgent cm = CredentialsManager.getInstance();
431 try {
432 PasswordAuthentication pa = new PasswordAuthentication(
433 tfProxyHttpUser.getText().trim(),
434 tfProxyHttpPassword.getPassword()
435 );
436 cm.store(RequestorType.PROXY, tfProxyHttpHost.getText(), pa);
437 } catch(CredentialsAgentException e) {
438 Main.error(e);
439 }
440 }
441}
Note: See TracBrowser for help on using the repository browser.