source: josm/trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java@ 6524

Last change on this file since 6524 was 6523, checked in by Don-vip, 10 years ago

Ask user to change proxy settings when proxy errors occur at startup (useful when a laptop is often used between two locations with different proxy settings)

  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.net.InetSocketAddress;
8import java.net.Proxy;
9import java.net.Proxy.Type;
10import java.net.ProxySelector;
11import java.net.SocketAddress;
12import java.net.URI;
13import java.util.Collections;
14import java.util.HashSet;
15import java.util.List;
16import java.util.Set;
17import java.util.TreeSet;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel;
21import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel.ProxyPolicy;
22
23/**
24 * This is the default proxy selector used in JOSM.
25 *
26 */
27public class DefaultProxySelector extends ProxySelector {
28 /**
29 * The {@link ProxySelector} provided by the JDK will retrieve proxy information
30 * from the system settings, if the system property <tt>java.net.useSystemProxies</tt>
31 * is defined <strong>at startup</strong>. It has no effect if the property is set
32 * later by the application.
33 *
34 * We therefore read the property at class loading time and remember it's value.
35 */
36 private static boolean JVM_WILL_USE_SYSTEM_PROXIES = false;
37 static {
38 String v = System.getProperty("java.net.useSystemProxies");
39 if (v != null && v.equals(Boolean.TRUE.toString())) {
40 JVM_WILL_USE_SYSTEM_PROXIES = true;
41 }
42 }
43
44 /**
45 * The {@link ProxySelector} provided by the JDK will retrieve proxy information
46 * from the system settings, if the system property <tt>java.net.useSystemProxies</tt>
47 * is defined <strong>at startup</strong>. If the property is set later by the application,
48 * this has no effect.
49 *
50 * @return true, if <tt>java.net.useSystemProxies</tt> was set to true at class initialization time
51 *
52 */
53 public static boolean willJvmRetrieveSystemProxies() {
54 return JVM_WILL_USE_SYSTEM_PROXIES;
55 }
56
57 private ProxyPolicy proxyPolicy;
58 private InetSocketAddress httpProxySocketAddress;
59 private InetSocketAddress socksProxySocketAddress;
60 private ProxySelector delegate;
61
62 private final Set<String> errorResources = new HashSet<String>();
63 private final Set<String> errorMessages = new HashSet<String>();
64
65 /**
66 * A typical example is:
67 * <pre>
68 * PropertySelector delegate = PropertySelector.getDefault();
69 * PropertySelector.setDefault(new DefaultPropertySelector(delegate));
70 * </pre>
71 *
72 * @param delegate the proxy selector to delegate to if system settings are used. Usually
73 * this is the proxy selector found by ProxySelector.getDefault() before this proxy
74 * selector is installed
75 */
76 public DefaultProxySelector(ProxySelector delegate) {
77 this.delegate = delegate;
78 initFromPreferences();
79 }
80
81 protected int parseProxyPortValue(String property, String value) {
82 if (value == null) return 0;
83 int port = 0;
84 try {
85 port = Integer.parseInt(value);
86 } catch (NumberFormatException e) {
87 Main.error(tr("Unexpected format for port number in in preference ''{0}''. Got ''{1}''.", property, value));
88 Main.error(tr("The proxy will not be used."));
89 return 0;
90 }
91 if (port <= 0 || port > 65535) {
92 Main.error(tr("Illegal port number in preference ''{0}''. Got {1}.", property, port));
93 Main.error(tr("The proxy will not be used."));
94 return 0;
95 }
96 return port;
97 }
98
99 /**
100 * Initializes the proxy selector from the setting in the preferences.
101 *
102 */
103 public void initFromPreferences() {
104 String value = Main.pref.get(ProxyPreferencesPanel.PROXY_POLICY);
105 if (value.length() == 0) {
106 proxyPolicy = ProxyPolicy.NO_PROXY;
107 } else {
108 proxyPolicy = ProxyPolicy.fromName(value);
109 if (proxyPolicy == null) {
110 Main.warn(tr("Unexpected value for preference ''{0}'' found. Got ''{1}''. Will use no proxy.", ProxyPreferencesPanel.PROXY_POLICY, value));
111 proxyPolicy = ProxyPolicy.NO_PROXY;
112 }
113 }
114 String host = Main.pref.get(ProxyPreferencesPanel.PROXY_HTTP_HOST, null);
115 int port = parseProxyPortValue(ProxyPreferencesPanel.PROXY_HTTP_PORT, Main.pref.get(ProxyPreferencesPanel.PROXY_HTTP_PORT, null));
116 httpProxySocketAddress = null;
117 if (proxyPolicy.equals(ProxyPolicy.USE_HTTP_PROXY)) {
118 if (host != null && !host.trim().isEmpty() && port > 0) {
119 httpProxySocketAddress = new InetSocketAddress(host, port);
120 } else {
121 Main.warn(tr("Unexpected parameters for HTTP proxy. Got host ''{0}'' and port ''{1}''.", host, port));
122 Main.warn(tr("The proxy will not be used."));
123 }
124 }
125
126 host = Main.pref.get(ProxyPreferencesPanel.PROXY_SOCKS_HOST, null);
127 port = parseProxyPortValue(ProxyPreferencesPanel.PROXY_SOCKS_PORT, Main.pref.get(ProxyPreferencesPanel.PROXY_SOCKS_PORT, null));
128 socksProxySocketAddress = null;
129 if (proxyPolicy.equals(ProxyPolicy.USE_SOCKS_PROXY)) {
130 if (host != null && !host.trim().isEmpty() && port > 0) {
131 socksProxySocketAddress = new InetSocketAddress(host,port);
132 } else {
133 Main.warn(tr("Unexpected parameters for SOCKS proxy. Got host ''{0}'' and port ''{1}''.", host, port));
134 Main.warn(tr("The proxy will not be used."));
135 }
136 }
137 }
138
139 @Override
140 public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
141 // Just log something. The network stack will also throw an exception which will be caught somewhere else
142 Main.error(tr("Connection to proxy ''{0}'' for URI ''{1}'' failed. Exception was: {2}", sa.toString(), uri.toString(), ioe.toString()));
143 // Remember errors to give a friendly user message asking to review proxy configuration
144 errorResources.add(uri.toString());
145 errorMessages.add(ioe.toString());
146 }
147
148 /**
149 * Returns the set of current proxy resources that failed to be retrieved.
150 * @return the set of current proxy resources that failed to be retrieved
151 * @since 6523
152 */
153 public final Set<String> getErrorResources() {
154 return new TreeSet<String>(errorResources);
155 }
156
157 /**
158 * Returns the set of current proxy error messages.
159 * @return the set of current proxy error messages
160 * @since 6523
161 */
162 public final Set<String> getErrorMessages() {
163 return new TreeSet<String>(errorMessages);
164 }
165
166 /**
167 * Clear the sets of failed resources and error messages.
168 * @since 6523
169 */
170 public final void clearErrors() {
171 errorResources.clear();
172 errorMessages.clear();
173 }
174
175 /**
176 * Determines if proxy errors have occured.
177 * @return {@code true} if errors have occured, {@code false} otherwise.
178 * @since 6523
179 */
180 public final boolean hasErrors() {
181 return !errorResources.isEmpty();
182 }
183
184 @Override
185 public List<Proxy> select(URI uri) {
186 Proxy proxy;
187 switch(proxyPolicy) {
188 case USE_SYSTEM_SETTINGS:
189 if (!JVM_WILL_USE_SYSTEM_PROXIES) {
190 Main.warn(tr("The JVM is not configured to lookup proxies from the system settings. The property ''java.net.useSystemProxies'' was missing at startup time. Will not use a proxy."));
191 return Collections.singletonList(Proxy.NO_PROXY);
192 }
193 // delegate to the former proxy selector
194 List<Proxy> ret = delegate.select(uri);
195 return ret;
196 case NO_PROXY:
197 return Collections.singletonList(Proxy.NO_PROXY);
198 case USE_HTTP_PROXY:
199 if (httpProxySocketAddress == null)
200 return Collections.singletonList(Proxy.NO_PROXY);
201 proxy = new Proxy(Type.HTTP, httpProxySocketAddress);
202 return Collections.singletonList(proxy);
203 case USE_SOCKS_PROXY:
204 if (socksProxySocketAddress == null)
205 return Collections.singletonList(Proxy.NO_PROXY);
206 proxy = new Proxy(Type.SOCKS, socksProxySocketAddress);
207 return Collections.singletonList(proxy);
208 }
209 // should not happen
210 return null;
211 }
212}
Note: See TracBrowser for help on using the repository browser.