// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.io;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.MessageFormat;
import javax.swing.JOptionPane;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.ExtensionFileFilter;
import org.openstreetmap.josm.gui.layer.Layer;
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
public class OsmExporter extends FileExporter {
public OsmExporter() {
super(new ExtensionFileFilter("osm,xml", "osm", tr("OSM Server Files") + " (*.osm *.xml)"));
}
public OsmExporter(ExtensionFileFilter filter) {
super(filter);
}
@Override
public boolean acceptFile(File pathname, Layer layer) {
if (!(layer instanceof OsmDataLayer))
return false;
return super.acceptFile(pathname, layer);
}
@Override
public void exportData(File file, Layer layer) throws IOException {
if (layer instanceof OsmDataLayer) {
save(file, (OsmDataLayer) layer);
} else
throw new IllegalArgumentException(MessageFormat.format("Expected instance of OsmDataLayer. Got ''{0}''.", layer
.getClass().getName()));
}
protected OutputStream getOutputStream(File file) throws FileNotFoundException, IOException {
return new FileOutputStream(file);
}
private void save(File file, OsmDataLayer layer) {
File tmpFile = null;
try {
// use a tmp file because if something errors out in the
// process of writing the file, we might just end up with
// a truncated file. That can destroy lots of work.
if (file.exists()) {
tmpFile = new File(file.getPath() + "~");
copy(file, tmpFile);
}
// create outputstream and wrap it with gzip or bzip, if necessary
OutputStream out = getOutputStream(file);
Writer writer = new OutputStreamWriter(out, "UTF-8");
OsmWriter w = new OsmWriter(new PrintWriter(writer), false, layer.data.getVersion());
w.header();
w.writeDataSources(layer.data);
w.writeContent(layer.data);
w.footer();
w.close();
// FIXME - how to close?
if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null)) {
tmpFile.delete();
}
layer.onPostSaveToFile();
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(
Main.parent,
tr("<html>An error occurred while saving.<br>Error is:<br>{0}</html>", e.getMessage()),
tr("Error"),
JOptionPane.ERROR_MESSAGE
);
try {
// if the file save failed, then the tempfile will not
// be deleted. So, restore the backup if we made one.
if (tmpFile != null && tmpFile.exists()) {
copy(tmpFile, file);
}
} catch (IOException e2) {
e2.printStackTrace();
JOptionPane.showMessageDialog(
Main.parent,
tr("<html>An error occurred while restoring backup file.<br>Error is:<br>{0}</html>", e2.getMessage()),
tr("Error"),
JOptionPane.ERROR_MESSAGE
);
}
}
}
private void copy(File src, File dst) throws IOException {
FileInputStream srcStream;
FileOutputStream dstStream;
try {
srcStream = new FileInputStream(src);
dstStream = new FileOutputStream(dst);
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(Main.parent, tr("Could not back up file. Exception is: {0}", e
.getMessage()), tr("Error"), JOptionPane.ERROR_MESSAGE);
return;
}
byte buf[] = new byte[1 << 16];
int len;
while ((len = srcStream.read(buf)) != -1) {
dstStream.write(buf, 0, len);
}
srcStream.close();
dstStream.close();
}
}