source: josm/trunk/src/org/openstreetmap/josm/io/OsmExporter.java@ 12119

Last change on this file since 12119 was 11848, checked in by Don-vip, 7 years ago

fix #14613 - Special HTML characters not escaped in GUI error messages

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.File;
7import java.io.IOException;
8import java.io.OutputStream;
9import java.io.OutputStreamWriter;
10import java.io.PrintWriter;
11import java.io.Writer;
12import java.nio.charset.StandardCharsets;
13import java.text.MessageFormat;
14
15import javax.swing.JOptionPane;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.actions.ExtensionFileFilter;
19import org.openstreetmap.josm.gui.layer.Layer;
20import org.openstreetmap.josm.gui.layer.OsmDataLayer;
21import org.openstreetmap.josm.tools.Utils;
22
23/**
24 * Exports data to an .osm file.
25 * @since 1949
26 */
27public class OsmExporter extends FileExporter {
28
29 /**
30 * Constructs a new {@code OsmExporter}.
31 */
32 public OsmExporter() {
33 super(new ExtensionFileFilter(
34 "osm,xml", "osm", tr("OSM Server Files") + " (*.osm)"));
35 }
36
37 /**
38 * Constructs a new {@code OsmExporter}.
39 * @param filter The extension file filter
40 */
41 public OsmExporter(ExtensionFileFilter filter) {
42 super(filter);
43 }
44
45 @Override
46 public boolean acceptFile(File pathname, Layer layer) {
47 if (!(layer instanceof OsmDataLayer))
48 return false;
49 return super.acceptFile(pathname, layer);
50 }
51
52 @Override
53 public void exportData(File file, Layer layer) throws IOException {
54 exportData(file, layer, false);
55 }
56
57 /**
58 * Exports OSM data to the given file.
59 * @param file Output file
60 * @param layer Data layer. Must be an instance of {@link OsmDataLayer}.
61 * @param noBackup if {@code true}, the potential backup file created if the output file already exists will be deleted
62 * after a successful export
63 * @throws IllegalArgumentException if {@code layer} is not an instance of {@code OsmDataLayer}
64 */
65 public void exportData(File file, Layer layer, boolean noBackup) {
66 if (!(layer instanceof OsmDataLayer)) {
67 throw new IllegalArgumentException(
68 MessageFormat.format("Expected instance of OsmDataLayer. Got ''{0}''.", layer.getClass().getName()));
69 }
70 save(file, (OsmDataLayer) layer, noBackup);
71 }
72
73 protected static OutputStream getOutputStream(File file) throws IOException {
74 return Compression.getCompressedFileOutputStream(file);
75 }
76
77 private void save(File file, OsmDataLayer layer, boolean noBackup) {
78 File tmpFile = null;
79 try {
80 // use a tmp file because if something errors out in the process of writing the file,
81 // we might just end up with a truncated file. That can destroy lots of work.
82 if (file.exists()) {
83 tmpFile = new File(file.getPath() + '~');
84 Utils.copyFile(file, tmpFile);
85 }
86
87 doSave(file, layer);
88 if ((noBackup || !Main.pref.getBoolean("save.keepbackup", false)) && tmpFile != null) {
89 Utils.deleteFile(tmpFile);
90 }
91 layer.onPostSaveToFile();
92 } catch (IOException e) {
93 Main.error(e);
94 JOptionPane.showMessageDialog(
95 Main.parent,
96 tr("<html>An error occurred while saving.<br>Error is:<br>{0}</html>",
97 Utils.escapeReservedCharactersHTML(e.getMessage())),
98 tr("Error"),
99 JOptionPane.ERROR_MESSAGE
100 );
101
102 try {
103 // if the file save failed, then the tempfile will not be deleted. So, restore the backup if we made one.
104 if (tmpFile != null && tmpFile.exists()) {
105 Utils.copyFile(tmpFile, file);
106 }
107 } catch (IOException e2) {
108 Main.error(e2);
109 JOptionPane.showMessageDialog(
110 Main.parent,
111 tr("<html>An error occurred while restoring backup file.<br>Error is:<br>{0}</html>",
112 Utils.escapeReservedCharactersHTML(e2.getMessage())),
113 tr("Error"),
114 JOptionPane.ERROR_MESSAGE
115 );
116 }
117 }
118 }
119
120 protected void doSave(File file, OsmDataLayer layer) throws IOException {
121 // create outputstream and wrap it with gzip or bzip, if necessary
122 try (
123 OutputStream out = getOutputStream(file);
124 Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8);
125 OsmWriter w = OsmWriterFactory.createOsmWriter(new PrintWriter(writer), false, layer.data.getVersion())
126 ) {
127 layer.data.getReadLock().lock();
128 try {
129 w.writeLayer(layer);
130 } finally {
131 layer.data.getReadLock().unlock();
132 }
133 }
134 }
135}
Note: See TracBrowser for help on using the repository browser.