source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/server/OsmApiUrlInputPanel.java@ 10212

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

sonar - squid:S2221 - "Exception" should not be caught when not required by called methods

  • Property svn:eol-style set to native
File size: 11.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;
5
6import java.awt.Font;
7import java.awt.GridBagConstraints;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.event.ActionEvent;
11import java.awt.event.ActionListener;
12import java.awt.event.FocusAdapter;
13import java.awt.event.FocusEvent;
14import java.awt.event.ItemEvent;
15import java.awt.event.ItemListener;
16import java.net.MalformedURLException;
17import java.net.URL;
18import java.util.Arrays;
19
20import javax.swing.AbstractAction;
21import javax.swing.JCheckBox;
22import javax.swing.JComponent;
23import javax.swing.JLabel;
24import javax.swing.JPanel;
25import javax.swing.SwingUtilities;
26import javax.swing.event.DocumentEvent;
27import javax.swing.event.DocumentListener;
28import javax.swing.text.JTextComponent;
29
30import org.openstreetmap.josm.Main;
31import org.openstreetmap.josm.data.preferences.CollectionProperty;
32import org.openstreetmap.josm.gui.SideButton;
33import org.openstreetmap.josm.gui.help.HelpUtil;
34import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
35import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
36import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
37import org.openstreetmap.josm.io.OsmApi;
38import org.openstreetmap.josm.io.OsmApiInitializationException;
39import org.openstreetmap.josm.io.OsmTransferCanceledException;
40import org.openstreetmap.josm.tools.ImageProvider;
41import org.openstreetmap.josm.tools.Utils;
42
43/**
44 * Component allowing input os OSM API URL.
45 */
46public class OsmApiUrlInputPanel extends JPanel {
47
48 /**
49 * OSM API URL property key.
50 */
51 public static final String API_URL_PROP = OsmApiUrlInputPanel.class.getName() + ".apiUrl";
52
53 private final JLabel lblValid = new JLabel();
54 private final JLabel lblApiUrl = new JLabel(tr("OSM Server URL:"));
55 private final HistoryComboBox tfOsmServerUrl = new HistoryComboBox();
56 private transient ApiUrlValidator valOsmServerUrl;
57 private SideButton btnTest;
58 /** indicates whether to use the default OSM URL or not */
59 private JCheckBox cbUseDefaultServerUrl;
60 private final transient CollectionProperty SERVER_URL_HISTORY = new CollectionProperty("osm-server.url-history", Arrays.asList(
61 "http://api06.dev.openstreetmap.org/api", "http://master.apis.dev.openstreetmap.org/api"));
62
63 private transient ApiUrlPropagator propagator;
64
65 /**
66 * Constructs a new {@code OsmApiUrlInputPanel}.
67 */
68 public OsmApiUrlInputPanel() {
69 build();
70 HelpUtil.setHelpContext(this, HelpUtil.ht("/Preferences/Connection#ApiUrl"));
71 }
72
73 protected JComponent buildDefaultServerUrlPanel() {
74 cbUseDefaultServerUrl = new JCheckBox(tr("<html>Use the default OSM server URL (<strong>{0}</strong>)</html>", OsmApi.DEFAULT_API_URL));
75 cbUseDefaultServerUrl.addItemListener(new UseDefaultServerUrlChangeHandler());
76 cbUseDefaultServerUrl.setFont(cbUseDefaultServerUrl.getFont().deriveFont(Font.PLAIN));
77 return cbUseDefaultServerUrl;
78 }
79
80 protected final void build() {
81 setLayout(new GridBagLayout());
82 GridBagConstraints gc = new GridBagConstraints();
83
84 // the checkbox for the default UL
85 gc.fill = GridBagConstraints.HORIZONTAL;
86 gc.anchor = GridBagConstraints.NORTHWEST;
87 gc.weightx = 1.0;
88 gc.insets = new Insets(0, 0, 0, 0);
89 gc.gridwidth = 4;
90 add(buildDefaultServerUrlPanel(), gc);
91
92
93 // the input field for the URL
94 gc.gridx = 0;
95 gc.gridy = 1;
96 gc.gridwidth = 1;
97 gc.weightx = 0.0;
98 gc.insets = new Insets(0, 0, 0, 3);
99 add(lblApiUrl, gc);
100
101 gc.gridx = 1;
102 gc.weightx = 1.0;
103 add(tfOsmServerUrl, gc);
104 lblApiUrl.setLabelFor(tfOsmServerUrl);
105 SelectAllOnFocusGainedDecorator.decorate(tfOsmServerUrl.getEditorComponent());
106 valOsmServerUrl = new ApiUrlValidator(tfOsmServerUrl.getEditorComponent());
107 valOsmServerUrl.validate();
108 propagator = new ApiUrlPropagator();
109 tfOsmServerUrl.addActionListener(propagator);
110 tfOsmServerUrl.addFocusListener(propagator);
111
112 gc.gridx = 2;
113 gc.weightx = 0.0;
114 add(lblValid, gc);
115
116 gc.gridx = 3;
117 gc.weightx = 0.0;
118 ValidateApiUrlAction actTest = new ValidateApiUrlAction();
119 tfOsmServerUrl.getEditorComponent().getDocument().addDocumentListener(actTest);
120 btnTest = new SideButton(actTest);
121 add(btnTest, gc);
122 }
123
124 /**
125 * Initializes the configuration panel with values from the preferences
126 */
127 public void initFromPreferences() {
128 String url = OsmApi.getOsmApi().getServerUrl();
129 tfOsmServerUrl.setPossibleItems(SERVER_URL_HISTORY.get());
130 if (OsmApi.DEFAULT_API_URL.equals(url.trim())) {
131 cbUseDefaultServerUrl.setSelected(true);
132 propagator.propagate(OsmApi.DEFAULT_API_URL);
133 } else {
134 cbUseDefaultServerUrl.setSelected(false);
135 tfOsmServerUrl.setText(url);
136 propagator.propagate(url);
137 }
138 }
139
140 /**
141 * Saves the values to the preferences
142 */
143 public void saveToPreferences() {
144 String oldUrl = OsmApi.getOsmApi().getServerUrl();
145 String hmiUrl = getStrippedApiUrl();
146 if (cbUseDefaultServerUrl.isSelected()) {
147 Main.pref.put("osm-server.url", null);
148 } else if (OsmApi.DEFAULT_API_URL.equals(hmiUrl)) {
149 Main.pref.put("osm-server.url", null);
150 } else {
151 Main.pref.put("osm-server.url", hmiUrl);
152 tfOsmServerUrl.addCurrentItemToHistory();
153 SERVER_URL_HISTORY.put(tfOsmServerUrl.getHistory());
154 }
155 String newUrl = OsmApi.getOsmApi().getServerUrl();
156
157 // When API URL changes, re-initialize API connection so we may adjust server-dependent settings.
158 if (!oldUrl.equals(newUrl)) {
159 try {
160 OsmApi.getOsmApi().initialize(null);
161 } catch (OsmTransferCanceledException | OsmApiInitializationException x) {
162 Main.warn(x);
163 }
164 }
165 }
166
167 /**
168 * Returns the entered API URL, stripped of leading and trailing white characters.
169 * @return the entered API URL, stripped of leading and trailing white characters.
170 * May be an empty string if nothing has been entered. In this case, it means the user wants to use {@link OsmApi#DEFAULT_API_URL}.
171 * @see Utils#strip(String)
172 * @since 6602
173 */
174 public final String getStrippedApiUrl() {
175 return Utils.strip(tfOsmServerUrl.getText());
176 }
177
178 class ValidateApiUrlAction extends AbstractAction implements DocumentListener {
179 private String lastTestedUrl;
180
181 ValidateApiUrlAction() {
182 putValue(NAME, tr("Validate"));
183 putValue(SHORT_DESCRIPTION, tr("Test the API URL"));
184 updateEnabledState();
185 }
186
187 @Override
188 public void actionPerformed(ActionEvent arg0) {
189 final String url = getStrippedApiUrl();
190 final ApiUrlTestTask task = new ApiUrlTestTask(OsmApiUrlInputPanel.this, url);
191 Main.worker.submit(task);
192 Runnable r = new Runnable() {
193 @Override
194 public void run() {
195 if (task.isCanceled())
196 return;
197 Runnable r = new Runnable() {
198 @Override
199 public void run() {
200 if (task.isSuccess()) {
201 lblValid.setIcon(ImageProvider.get("dialogs", "valid"));
202 lblValid.setToolTipText(tr("The API URL is valid."));
203 lastTestedUrl = url;
204 updateEnabledState();
205 } else {
206 lblValid.setIcon(ImageProvider.get("warning-small"));
207 lblValid.setToolTipText(tr("Validation failed. The API URL seems to be invalid."));
208 }
209 }
210 };
211 SwingUtilities.invokeLater(r);
212 }
213 };
214 Main.worker.submit(r);
215 }
216
217 protected final void updateEnabledState() {
218 String url = getStrippedApiUrl();
219 boolean enabled = !url.isEmpty() && !url.equals(lastTestedUrl);
220 if (enabled) {
221 lblValid.setIcon(null);
222 }
223 setEnabled(enabled);
224 }
225
226 @Override
227 public void changedUpdate(DocumentEvent arg0) {
228 updateEnabledState();
229 }
230
231 @Override
232 public void insertUpdate(DocumentEvent arg0) {
233 updateEnabledState();
234 }
235
236 @Override
237 public void removeUpdate(DocumentEvent arg0) {
238 updateEnabledState();
239 }
240 }
241
242 /**
243 * Enables or disables the API URL input.
244 * @param enabled {@code true} to enable input, {@code false} otherwise
245 */
246 public void setApiUrlInputEnabled(boolean enabled) {
247 lblApiUrl.setEnabled(enabled);
248 tfOsmServerUrl.setEnabled(enabled);
249 lblValid.setEnabled(enabled);
250 btnTest.setEnabled(enabled);
251 }
252
253 private static class ApiUrlValidator extends AbstractTextComponentValidator {
254 ApiUrlValidator(JTextComponent tc) {
255 super(tc);
256 }
257
258 @Override
259 public boolean isValid() {
260 if (getComponent().getText().trim().isEmpty())
261 return false;
262
263 try {
264 new URL(getComponent().getText().trim());
265 return true;
266 } catch (MalformedURLException e) {
267 return false;
268 }
269 }
270
271 @Override
272 public void validate() {
273 if (getComponent().getText().trim().isEmpty()) {
274 feedbackInvalid(tr("OSM API URL must not be empty. Please enter the OSM API URL."));
275 return;
276 }
277 if (!isValid()) {
278 feedbackInvalid(tr("The current value is not a valid URL"));
279 } else {
280 feedbackValid(tr("Please enter the OSM API URL."));
281 }
282 }
283 }
284
285 /**
286 * Handles changes in the default URL
287 */
288 class UseDefaultServerUrlChangeHandler implements ItemListener {
289 @Override
290 public void itemStateChanged(ItemEvent e) {
291 switch(e.getStateChange()) {
292 case ItemEvent.SELECTED:
293 setApiUrlInputEnabled(false);
294 propagator.propagate(OsmApi.DEFAULT_API_URL);
295 break;
296 case ItemEvent.DESELECTED:
297 setApiUrlInputEnabled(true);
298 valOsmServerUrl.validate();
299 tfOsmServerUrl.requestFocusInWindow();
300 propagator.propagate();
301 break;
302 }
303 }
304 }
305
306 class ApiUrlPropagator extends FocusAdapter implements ActionListener {
307 protected void propagate() {
308 propagate(getStrippedApiUrl());
309 }
310
311 protected void propagate(String url) {
312 firePropertyChange(API_URL_PROP, null, url);
313 }
314
315 @Override
316 public void actionPerformed(ActionEvent e) {
317 propagate();
318 }
319
320 @Override
321 public void focusLost(FocusEvent arg0) {
322 propagate();
323 }
324 }
325}
Note: See TracBrowser for help on using the repository browser.