source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/server/ApiUrlTestTask.java@ 9309

Last change on this file since 9309 was 9309, checked in by simon04, 8 years ago

see #12292 - Allow to disconnect HttpClient in connecting phase

  • Property svn:eol-style set to native
File size: 7.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;
5
6import java.awt.Component;
7import java.io.IOException;
8import java.net.HttpURLConnection;
9import java.net.MalformedURLException;
10import java.net.URL;
11
12import javax.swing.JOptionPane;
13import javax.xml.parsers.ParserConfigurationException;
14
15import org.openstreetmap.josm.Main;
16import org.openstreetmap.josm.gui.HelpAwareOptionPane;
17import org.openstreetmap.josm.gui.PleaseWaitRunnable;
18import org.openstreetmap.josm.gui.help.HelpUtil;
19import org.openstreetmap.josm.io.Capabilities;
20import org.openstreetmap.josm.io.OsmTransferException;
21import org.openstreetmap.josm.tools.CheckParameterUtil;
22import org.openstreetmap.josm.tools.HttpClient;
23import org.xml.sax.InputSource;
24import org.xml.sax.SAXException;
25
26/**
27 * This is an asynchronous task for testing whether an URL points to an OSM API server.
28 * It tries to retrieve capabilities from the given URL. If it succeeds, the method
29 * {@link #isSuccess()} replies true, otherwise false.
30 * @since 2745
31 */
32public class ApiUrlTestTask extends PleaseWaitRunnable {
33
34 private final String url;
35 private boolean canceled;
36 private boolean success;
37 private final Component parent;
38 private HttpClient connection;
39
40 /**
41 * Constructs a new {@code ApiUrlTestTask}.
42 *
43 * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog is displayed
44 * @param url the url. Must not be null.
45 * @throws IllegalArgumentException if url is null.
46 */
47 public ApiUrlTestTask(Component parent, String url) {
48 super(parent, tr("Testing OSM API URL ''{0}''", url), false /* don't ignore exceptions */);
49 CheckParameterUtil.ensureParameterNotNull(url, "url");
50 this.parent = parent;
51 this.url = url;
52 }
53
54 protected void alertInvalidUrl(String url) {
55 HelpAwareOptionPane.showMessageDialogInEDT(
56 parent,
57 tr("<html>"
58 + "''{0}'' is not a valid OSM API URL.<br>"
59 + "Please check the spelling and validate again."
60 + "</html>",
61 url
62 ),
63 tr("Invalid API URL"),
64 JOptionPane.ERROR_MESSAGE,
65 HelpUtil.ht("/Preferences/Connection#InvalidAPIUrl")
66 );
67 }
68
69 protected void alertInvalidCapabilitiesUrl(String url) {
70 HelpAwareOptionPane.showMessageDialogInEDT(
71 parent,
72 tr("<html>"
73 + "Failed to build URL ''{0}'' for validating the OSM API server.<br>"
74 + "Please check the spelling of ''{1}'' and validate again."
75 +"</html>",
76 url,
77 getNormalizedApiUrl()
78 ),
79 tr("Invalid API URL"),
80 JOptionPane.ERROR_MESSAGE,
81 HelpUtil.ht("/Preferences/Connection#InvalidAPIGetChangesetsUrl")
82 );
83 }
84
85 protected void alertConnectionFailed() {
86 HelpAwareOptionPane.showMessageDialogInEDT(
87 parent,
88 tr("<html>"
89 + "Failed to connect to the URL ''{0}''.<br>"
90 + "Please check the spelling of ''{1}'' and your Internet connection and validate again."
91 +"</html>",
92 url,
93 getNormalizedApiUrl()
94 ),
95 tr("Connection to API failed"),
96 JOptionPane.ERROR_MESSAGE,
97 HelpUtil.ht("/Preferences/Connection#ConnectionToAPIFailed")
98 );
99 }
100
101 protected void alertInvalidServerResult(int retCode) {
102 HelpAwareOptionPane.showMessageDialogInEDT(
103 parent,
104 tr("<html>"
105 + "Failed to retrieve a list of changesets from the OSM API server at<br>"
106 + "''{1}''. The server responded with the return code {0} instead of 200.<br>"
107 + "Please check the spelling of ''{1}'' and validate again."
108 + "</html>",
109 retCode,
110 getNormalizedApiUrl()
111 ),
112 tr("Connection to API failed"),
113 JOptionPane.ERROR_MESSAGE,
114 HelpUtil.ht("/Preferences/Connection#InvalidServerResult")
115 );
116 }
117
118 protected void alertInvalidCapabilities() {
119 HelpAwareOptionPane.showMessageDialogInEDT(
120 parent,
121 tr("<html>"
122 + "The OSM API server at ''{0}'' did not return a valid response.<br>"
123 + "It is likely that ''{0}'' is not an OSM API server.<br>"
124 + "Please check the spelling of ''{0}'' and validate again."
125 + "</html>",
126 getNormalizedApiUrl()
127 ),
128 tr("Connection to API failed"),
129 JOptionPane.ERROR_MESSAGE,
130 HelpUtil.ht("/Preferences/Connection#InvalidSettings")
131 );
132 }
133
134 @Override
135 protected void cancel() {
136 canceled = true;
137 synchronized (this) {
138 if (connection != null) {
139 connection.disconnect();
140 }
141 }
142 }
143
144 @Override
145 protected void finish() {}
146
147 /**
148 * Removes leading and trailing whitespace from the API URL and removes trailing '/'.
149 *
150 * @return the normalized API URL
151 */
152 protected String getNormalizedApiUrl() {
153 String apiUrl = url.trim();
154 while (apiUrl.endsWith("/")) {
155 apiUrl = apiUrl.substring(0, apiUrl.lastIndexOf('/'));
156 }
157 return apiUrl;
158 }
159
160 @Override
161 protected void realRun() throws SAXException, IOException, OsmTransferException {
162 try {
163 try {
164 new URL(getNormalizedApiUrl());
165 } catch (MalformedURLException e) {
166 alertInvalidUrl(getNormalizedApiUrl());
167 return;
168 }
169 URL capabilitiesUrl;
170 String getCapabilitiesUrl = getNormalizedApiUrl() + "/0.6/capabilities";
171 try {
172 capabilitiesUrl = new URL(getCapabilitiesUrl);
173 } catch (MalformedURLException e) {
174 alertInvalidCapabilitiesUrl(getCapabilitiesUrl);
175 return;
176 }
177
178 synchronized (this) {
179 connection = HttpClient.create(capabilitiesUrl);
180 connection.connect();
181 }
182
183 if (connection.getResponse().getResponseCode() != HttpURLConnection.HTTP_OK) {
184 alertInvalidServerResult(connection.getResponse().getResponseCode());
185 return;
186 }
187
188 try {
189 Capabilities.CapabilitiesParser.parse(new InputSource(connection.getResponse().getContent()));
190 } catch (SAXException | ParserConfigurationException e) {
191 Main.warn(e.getMessage());
192 alertInvalidCapabilities();
193 return;
194 }
195 success = true;
196 } catch (IOException e) {
197 if (canceled)
198 // ignore exceptions
199 return;
200 Main.error(e);
201 alertConnectionFailed();
202 return;
203 }
204 }
205
206 /**
207 * Determines if the test has been canceled.
208 * @return {@code true} if canceled, {@code false} otherwise
209 */
210 public boolean isCanceled() {
211 return canceled;
212 }
213
214 /**
215 * Determines if the test has succeeded.
216 * @return {@code true} if success, {@code false} otherwise
217 */
218 public boolean isSuccess() {
219 return success;
220 }
221}
Note: See TracBrowser for help on using the repository browser.