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

Last change on this file was 19050, checked in by taylor.smock, 45 hours ago

Revert most var changes from r19048, fix most new compile warnings and checkstyle issues

Also, document why various ErrorProne checks were originally disabled and fix
generic SonarLint issues.

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