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 }