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.OsmApi; 018import org.openstreetmap.josm.io.OsmApiInitializationException; 019import org.openstreetmap.josm.io.OsmTransferCanceledException; 020 021public class ApiPreconditionCheckerHook implements UploadHook { 022 023 @Override 024 public boolean checkUpload(APIDataSet apiData) { 025 OsmApi api = OsmApi.getOsmApi(); 026 try { 027 // FIXME: this should run asynchronously and a progress monitor 028 // should be displayed. 029 api.initialize(NullProgressMonitor.INSTANCE); 030 long maxNodes = 0; 031 if (api.getCapabilities().isDefined("waynodes", "maximum")) { 032 maxNodes = api.getCapabilities().getLong("waynodes","maximum"); 033 } 034 if (maxNodes > 0) { 035 if( !checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes)) 036 return false; 037 if( !checkMaxNodes(apiData.getPrimitivesToUpdate(), maxNodes)) 038 return false; 039 if( !checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes)) 040 return false; 041 } 042 } catch(OsmTransferCanceledException e){ 043 return false; 044 } catch (OsmApiInitializationException e) { 045 ExceptionDialogUtil.explainOsmTransferException(e); 046 return false; 047 } 048 return true; 049 } 050 051 private boolean checkMaxNodes(Collection<OsmPrimitive> primitives, long maxNodes) { 052 for (OsmPrimitive osmPrimitive : primitives) { 053 for (String key: osmPrimitive.keySet()) { 054 String value = osmPrimitive.get(key); 055 if (key.length() > 255) { 056 if (osmPrimitive.isDeleted()) { 057 // if OsmPrimitive is going to be deleted we automatically shorten the value 058 Main.warn( 059 tr("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}