001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.actions.upload;
003
004 import static org.openstreetmap.josm.tools.I18n.tr;
005
006 import java.util.Collection;
007 import java.util.Collections;
008
009 import javax.swing.JOptionPane;
010
011 import org.openstreetmap.josm.Main;
012 import org.openstreetmap.josm.data.APIDataSet;
013 import org.openstreetmap.josm.data.osm.OsmPrimitive;
014 import org.openstreetmap.josm.data.osm.Way;
015 import org.openstreetmap.josm.gui.ExceptionDialogUtil;
016 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
017 import org.openstreetmap.josm.io.OsmApi;
018 import org.openstreetmap.josm.io.OsmApiInitializationException;
019 import org.openstreetmap.josm.io.OsmTransferCanceledException;
020
021 public class ApiPreconditionCheckerHook implements UploadHook {
022
023 public boolean checkUpload(APIDataSet apiData) {
024 OsmApi api = OsmApi.getOsmApi();
025 try {
026 // FIXME: this should run asynchronously and a progress monitor
027 // should be displayed.
028 api.initialize(NullProgressMonitor.INSTANCE);
029 long maxNodes = 0;
030 if (api.getCapabilities().isDefined("waynodes", "maximum")) {
031 maxNodes = api.getCapabilities().getLong("waynodes","maximum");
032 }
033 if (maxNodes > 0) {
034 if( !checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes))
035 return false;
036 if( !checkMaxNodes(apiData.getPrimitivesToUpdate(), maxNodes))
037 return false;
038 if( !checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes))
039 return false;
040 }
041 } catch(OsmTransferCanceledException e){
042 return false;
043 } catch (OsmApiInitializationException e) {
044 ExceptionDialogUtil.explainOsmTransferException(e);
045 return false;
046 }
047 return true;
048 }
049
050 private boolean checkMaxNodes(Collection<OsmPrimitive> primitives, long maxNodes) {
051 for (OsmPrimitive osmPrimitive : primitives) {
052 for (String key: osmPrimitive.keySet()) {
053 String value = osmPrimitive.get(key);
054 if(key.length() > 255) {
055 if (osmPrimitive.isDeleted()) {
056 // if OsmPrimitive is going to be deleted we automatically shorten the
057 // value
058 System.out.println(
059 tr("Warning: automatically truncating value of tag ''{0}'' on deleted object {1}",
060 key,
061 Long.toString(osmPrimitive.getId())
062 )
063 );
064 osmPrimitive.put(key, value.substring(0, 255));
065 continue;
066 }
067 JOptionPane.showMessageDialog(Main.parent,
068 tr("Length of value for tag ''{0}'' on object {1} exceeds the max. allowed length {2}. Values length is {3}.",
069 key, Long.toString(osmPrimitive.getId()), 255, value.length()
070 ),
071 tr("Precondition Violation"),
072 JOptionPane.ERROR_MESSAGE
073 );
074 Main.main.getCurrentDataSet().setSelected(Collections.singleton(osmPrimitive));
075 return false;
076 }
077 }
078
079 if (osmPrimitive instanceof Way &&
080 ((Way)osmPrimitive).getNodesCount() > maxNodes) {
081 JOptionPane.showMessageDialog(
082 Main.parent,
083 tr("{0} nodes in way {1} exceed the max. allowed number of nodes {2}",
084 ((Way)osmPrimitive).getNodesCount(),
085 Long.toString(osmPrimitive.getId()),
086 maxNodes
087 ),
088 tr("API Capabilities Violation"),
089 JOptionPane.ERROR_MESSAGE
090 );
091 Main.main.getCurrentDataSet().setSelected(Collections.singleton(osmPrimitive));
092 return false;
093 }
094 }
095 return true;
096 }
097 }