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