source: josm/trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java@ 8345

Last change on this file since 8345 was 8308, checked in by Don-vip, 9 years ago

fix potential NPEs and Sonar issues related to serialization

  • Property svn:eol-style set to native
File size: 6.2 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.IOException;
7import java.io.InputStream;
8import java.io.InputStreamReader;
9import java.io.StringReader;
10import java.nio.charset.StandardCharsets;
11
12import javax.xml.parsers.ParserConfigurationException;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.osm.ChangesetDataSet;
16import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType;
17import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
19import org.openstreetmap.josm.tools.CheckParameterUtil;
20import org.openstreetmap.josm.tools.Utils;
21import org.openstreetmap.josm.tools.XmlParsingException;
22import org.xml.sax.Attributes;
23import org.xml.sax.InputSource;
24import org.xml.sax.SAXException;
25import org.xml.sax.SAXParseException;
26
27/**
28 * Parser for OSM changeset content.
29 * @since 2688
30 */
31public class OsmChangesetContentParser {
32
33 private InputSource source;
34 private final ChangesetDataSet data = new ChangesetDataSet();
35
36 private class Parser extends AbstractParser {
37
38 /** the current change modification type */
39 private ChangesetDataSet.ChangesetModificationType currentModificationType;
40
41 @Override
42 protected void throwException(String message) throws XmlParsingException {
43 throw new XmlParsingException(message).rememberLocation(locator);
44 }
45
46 @Override
47 protected void throwException(String message, Exception e) throws XmlParsingException {
48 throw new XmlParsingException(message, e).rememberLocation(locator);
49 }
50
51 @Override
52 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
53 if (super.doStartElement(qName, atts)) {
54 // done
55 return;
56 }
57 switch (qName) {
58 case "osmChange":
59 // do nothing
60 break;
61 case "create":
62 currentModificationType = ChangesetModificationType.CREATED;
63 break;
64 case "modify":
65 currentModificationType = ChangesetModificationType.UPDATED;
66 break;
67 case "delete":
68 currentModificationType = ChangesetModificationType.DELETED;
69 break;
70 default:
71 Main.warn(tr("Unsupported start element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
72 qName, locator.getLineNumber(), locator.getColumnNumber()));
73 }
74 }
75
76 @Override
77 public void endElement(String uri, String localName, String qName) throws SAXException {
78 switch (qName) {
79 case "node":
80 case "way":
81 case "relation":
82 if (currentModificationType == null) {
83 throwException(tr("Illegal document structure. Found node, way, or relation outside of ''create'', ''modify'', or ''delete''."));
84 }
85 data.put(currentPrimitive, currentModificationType);
86 break;
87 case "create":
88 case "modify":
89 case "delete":
90 currentModificationType = null;
91 break;
92 case "osmChange":
93 case "tag":
94 case "nd":
95 case "member":
96 // do nothing
97 break;
98 default:
99 Main.warn(tr("Unsupported end element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
100 qName, locator.getLineNumber(), locator.getColumnNumber()));
101 }
102 }
103
104 @Override
105 public void error(SAXParseException e) throws SAXException {
106 throwException(null, e);
107 }
108
109 @Override
110 public void fatalError(SAXParseException e) throws SAXException {
111 throwException(null, e);
112 }
113 }
114
115 /**
116 * Constructs a new {@code OsmChangesetContentParser}.
117 *
118 * @param source the input stream with the changeset content as XML document. Must not be null.
119 * @throws IllegalArgumentException if source is {@code null}.
120 */
121 @SuppressWarnings("resource")
122 public OsmChangesetContentParser(InputStream source) {
123 CheckParameterUtil.ensureParameterNotNull(source, "source");
124 this.source = new InputSource(new InputStreamReader(source, StandardCharsets.UTF_8));
125 }
126
127 /**
128 * Constructs a new {@code OsmChangesetContentParser}.
129 *
130 * @param source the input stream with the changeset content as XML document. Must not be null.
131 * @throws IllegalArgumentException if source is {@code null}.
132 */
133 public OsmChangesetContentParser(String source) {
134 CheckParameterUtil.ensureParameterNotNull(source, "source");
135 this.source = new InputSource(new StringReader(source));
136 }
137
138 /**
139 * Parses the content.
140 *
141 * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
142 * @return the parsed data
143 * @throws XmlParsingException if something went wrong. Check for chained
144 * exceptions.
145 */
146 public ChangesetDataSet parse(ProgressMonitor progressMonitor) throws XmlParsingException {
147 if (progressMonitor == null) {
148 progressMonitor = NullProgressMonitor.INSTANCE;
149 }
150 try {
151 progressMonitor.beginTask("");
152 progressMonitor.indeterminateSubTask(tr("Parsing changeset content ..."));
153 Utils.newSafeSAXParser().parse(source, new Parser());
154 } catch(XmlParsingException e) {
155 throw e;
156 } catch (ParserConfigurationException | SAXException | IOException e) {
157 throw new XmlParsingException(e);
158 } finally {
159 progressMonitor.finishTask();
160 }
161 return data;
162 }
163
164 /**
165 * Parses the content from the input source
166 *
167 * @return the parsed data
168 * @throws XmlParsingException if something went wrong. Check for chained
169 * exceptions.
170 */
171 public ChangesetDataSet parse() throws XmlParsingException {
172 return parse(null);
173 }
174}
Note: See TracBrowser for help on using the repository browser.