source: josm/trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java

Last change on this file was 19443, checked in by GerdP, 3 months ago

fix #24480: 19437 introduced client side tag checking impacting private server.

  • implement boolean preference upload.check-maxlength-value which allows to disable the maxlength check of tag values on upload
  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.upload;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Collection;
7import java.util.Collections;
8import java.util.Map;
9
10import javax.swing.JOptionPane;
11
12import org.openstreetmap.josm.data.APIDataSet;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.osm.Tagged;
15import org.openstreetmap.josm.data.osm.Way;
16import org.openstreetmap.josm.data.preferences.AbstractProperty;
17import org.openstreetmap.josm.data.preferences.BooleanProperty;
18import org.openstreetmap.josm.gui.ExceptionDialogUtil;
19import org.openstreetmap.josm.gui.MainApplication;
20import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
21import org.openstreetmap.josm.io.NetworkManager;
22import org.openstreetmap.josm.io.OnlineResource;
23import org.openstreetmap.josm.io.OsmApi;
24import org.openstreetmap.josm.io.OsmApiInitializationException;
25import org.openstreetmap.josm.io.OsmTransferCanceledException;
26import org.openstreetmap.josm.tools.Logging;
27import org.openstreetmap.josm.tools.Utils;
28
29/**
30 * Checks certain basic conditions, that are listed in the OSM API
31 * {@link org.openstreetmap.josm.io.Capabilities}.
32 */
33public class ApiPreconditionCheckerHook implements UploadHook {
34 static AbstractProperty<Boolean> PREF_LENGTH_CHECK = new BooleanProperty("upload.check-maxlength-value", true).cached();
35
36 @Override
37 public boolean checkUpload(APIDataSet apiData) {
38 OsmApi api = OsmApi.getOsmApi();
39 try {
40 if (NetworkManager.isOffline(OnlineResource.OSM_API)) {
41 return false;
42 }
43 // FIXME: this should run asynchronously and a progress monitor
44 // should be displayed.
45 api.initialize(NullProgressMonitor.INSTANCE);
46 long maxNodes = api.getCapabilities().getMaxWayNodes();
47 if (maxNodes > 0) {
48 if (!checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes))
49 return false;
50 if (!checkMaxNodes(apiData.getPrimitivesToUpdate(), maxNodes))
51 return false;
52 if (!checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes))
53 return false;
54 }
55 } catch (OsmTransferCanceledException e) {
56 Logging.trace(e);
57 return false;
58 } catch (OsmApiInitializationException e) {
59 ExceptionDialogUtil.explainOsmTransferException(e);
60 return false;
61 }
62 return true;
63 }
64
65 private static boolean checkMaxNodes(Collection<OsmPrimitive> primitives, long maxNodes) {
66 for (OsmPrimitive osmPrimitive : primitives) {
67 if (Boolean.TRUE.equals(PREF_LENGTH_CHECK.get()) && !valueLengthCheck(osmPrimitive)) {
68 return false;
69 }
70
71 if (osmPrimitive instanceof Way &&
72 ((Way) osmPrimitive).getNodesCount() > maxNodes) {
73 JOptionPane.showMessageDialog(
74 MainApplication.getMainFrame(),
75 tr("{0} nodes in way {1} exceed the max. allowed number of nodes {2}",
76 ((Way) osmPrimitive).getNodesCount(),
77 Long.toString(osmPrimitive.getId()),
78 maxNodes
79 ),
80 tr("API Capabilities Violation"),
81 JOptionPane.ERROR_MESSAGE
82 );
83 MainApplication.getLayerManager().getEditDataSet().setSelected(Collections.singleton(osmPrimitive));
84 return false;
85 }
86 }
87 return true;
88 }
89
90 /**
91 * Check that the tag values of a primitive are not too long.
92 * @param osmPrimitive the primitive to check
93 * @return false if any tag value of the primitive is too long, true else
94 */
95 private static boolean valueLengthCheck(OsmPrimitive osmPrimitive) {
96 for (Map.Entry<String, String> entry: osmPrimitive.getKeys().entrySet()) {
97 String key = entry.getKey();
98 String value = entry.getValue();
99 if (!Utils.checkCodePointCount(value, Tagged.MAX_TAG_LENGTH)) {
100 if (osmPrimitive.isDeleted()) {
101 // if OsmPrimitive is going to be deleted we automatically shorten the value
102 Logging.warn(
103 tr("Automatically truncating value of tag ''{0}'' on deleted object {1}",
104 key,
105 Long.toString(osmPrimitive.getId())
106 )
107 );
108 osmPrimitive.put(key, Utils.shortenString(value, Tagged.MAX_TAG_LENGTH));
109 continue;
110 }
111 JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
112 tr("Length of value for tag ''{0}'' on object {1} exceeds the max. allowed length {2}. Values length is {3}.",
113 key, Long.toString(osmPrimitive.getId()), Tagged.MAX_TAG_LENGTH, Utils.getCodePointCount(value)
114 ),
115 tr("Precondition violation"),
116 JOptionPane.ERROR_MESSAGE
117 );
118 MainApplication.getLayerManager().getEditDataSet().setSelected(Collections.singleton(osmPrimitive));
119 return false;
120 }
121 }
122 return true;
123 }
124}
Note: See TracBrowser for help on using the repository browser.