// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.actions.upload;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.Collection;
import java.util.Collections;
import javax.swing.JOptionPane;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.APIDataSet;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.gui.ExceptionDialogUtil;
import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
import org.openstreetmap.josm.io.OsmApi;
import org.openstreetmap.josm.io.OsmApiInitializationException;
import org.openstreetmap.josm.io.OsmTransferCanceledException;
public class ApiPreconditionCheckerHook implements UploadHook {
@Override
public boolean checkUpload(APIDataSet apiData) {
OsmApi api = OsmApi.getOsmApi();
try {
// FIXME: this should run asynchronously and a progress monitor
// should be displayed.
api.initialize(NullProgressMonitor.INSTANCE);
long maxNodes = 0;
if (api.getCapabilities().isDefined("waynodes", "maximum")) {
maxNodes = api.getCapabilities().getLong("waynodes","maximum");
}
if (maxNodes > 0) {
if( !checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes))
return false;
if( !checkMaxNodes(apiData.getPrimitivesToUpdate(), maxNodes))
return false;
if( !checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes))
return false;
}
} catch(OsmTransferCanceledException e){
return false;
} catch (OsmApiInitializationException e) {
ExceptionDialogUtil.explainOsmTransferException(e);
return false;
}
return true;
}
private boolean checkMaxNodes(Collection<OsmPrimitive> primitives, long maxNodes) {
for (OsmPrimitive osmPrimitive : primitives) {
for (String key: osmPrimitive.keySet()) {
String value = osmPrimitive.get(key);
if (key.length() > 255) {
if (osmPrimitive.isDeleted()) {
// if OsmPrimitive is going to be deleted we automatically shorten the value
Main.warn(
tr("Automatically truncating value of tag ''{0}'' on deleted object {1}",
key,
Long.toString(osmPrimitive.getId())
)
);
osmPrimitive.put(key, value.substring(0, 255));
continue;
}
JOptionPane.showMessageDialog(Main.parent,
tr("Length of value for tag ''{0}'' on object {1} exceeds the max. allowed length {2}. Values length is {3}.",
key, Long.toString(osmPrimitive.getId()), 255, value.length()
),
tr("Precondition Violation"),
JOptionPane.ERROR_MESSAGE
);
Main.main.getCurrentDataSet().setSelected(Collections.singleton(osmPrimitive));
return false;
}
}
if (osmPrimitive instanceof Way &&
((Way)osmPrimitive).getNodesCount() > maxNodes) {
JOptionPane.showMessageDialog(
Main.parent,
tr("{0} nodes in way {1} exceed the max. allowed number of nodes {2}",
((Way)osmPrimitive).getNodesCount(),
Long.toString(osmPrimitive.getId()),
maxNodes
),
tr("API Capabilities Violation"),
JOptionPane.ERROR_MESSAGE
);
Main.main.getCurrentDataSet().setSelected(Collections.singleton(osmPrimitive));
return false;
}
}
return true;
}
}