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

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

see #15229 - see #15182 - remove GUI references from DefaultProxySelector

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