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

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

Sonar/FindBugs - Replace singular fields by local variables

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