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

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

fix #8404 - workaround for JDK bug 6322854 (crash when inserting password from clipboard corrupted by KeePass)

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