source: josm/trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java@ 7206

Last change on this file since 7206 was 7012, checked in by Don-vip, 10 years ago

see #8465 - use String switch/case where applicable

  • Property svn:eol-style set to native
File size: 6.7 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.StringReader;
8import java.util.Collection;
9import java.util.Collections;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.Map;
13import java.util.Set;
14
15import javax.xml.parsers.ParserConfigurationException;
16import javax.xml.parsers.SAXParserFactory;
17
18import org.openstreetmap.josm.data.osm.Changeset;
19import org.openstreetmap.josm.data.osm.IPrimitive;
20import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
21import org.openstreetmap.josm.data.osm.PrimitiveId;
22import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
23import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
24import org.openstreetmap.josm.gui.progress.ProgressMonitor;
25import org.openstreetmap.josm.tools.CheckParameterUtil;
26import org.openstreetmap.josm.tools.XmlParsingException;
27import org.xml.sax.Attributes;
28import org.xml.sax.InputSource;
29import org.xml.sax.Locator;
30import org.xml.sax.SAXException;
31import org.xml.sax.helpers.DefaultHandler;
32
33public class DiffResultProcessor {
34
35 private static class DiffResultEntry {
36 public long new_id;
37 public int new_version;
38 }
39
40 /**
41 * mapping from old id to new id and version, the result of parsing the diff result
42 * replied by the server
43 */
44 private Map<PrimitiveId, DiffResultEntry> diffResults = new HashMap<>();
45 /**
46 * the set of processed primitives *after* the new id, the new version and the new changeset id
47 * is set
48 */
49 private Set<IPrimitive> processed;
50 /**
51 * the collection of primitives being uploaded
52 */
53 private Collection<? extends IPrimitive> primitives;
54
55 /**
56 * Creates a diff result reader
57 *
58 * @param primitives the collection of primitives which have been uploaded. If null,
59 * assumes an empty collection.
60 */
61 public DiffResultProcessor(Collection<? extends IPrimitive> primitives) {
62 if (primitives == null) {
63 primitives = Collections.emptyList();
64 }
65 this.primitives = primitives;
66 this.processed = new HashSet<>();
67 }
68
69 /**
70 * Parse the response from a diff upload to the OSM API.
71 *
72 * @param diffUploadResponse the response. Must not be null.
73 * @param progressMonitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null
74 * @throws IllegalArgumentException if diffUploadRequest is null
75 * @throws XmlParsingException if the diffUploadRequest can't be parsed successfully
76 *
77 */
78 public void parse(String diffUploadResponse, ProgressMonitor progressMonitor) throws XmlParsingException {
79 if (progressMonitor == null) {
80 progressMonitor = NullProgressMonitor.INSTANCE;
81 }
82 CheckParameterUtil.ensureParameterNotNull(diffUploadResponse, "diffUploadResponse");
83 try {
84 progressMonitor.beginTask(tr("Parsing response from server..."));
85 InputSource inputSource = new InputSource(new StringReader(diffUploadResponse));
86 SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new Parser());
87 } catch(XmlParsingException e) {
88 throw e;
89 } catch(IOException | ParserConfigurationException | SAXException e) {
90 throw new XmlParsingException(e);
91 } finally {
92 progressMonitor.finishTask();
93 }
94 }
95
96 /**
97 * Postprocesses the diff result read and parsed from the server.
98 *
99 * Uploaded objects are assigned their new id (if they got assigned a new
100 * id by the server), their new version (if the version was incremented),
101 * and the id of the changeset to which they were uploaded.
102 *
103 * @param cs the current changeset. Ignored if null.
104 * @param monitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
105 * @return the collection of processed primitives
106 */
107 protected Set<IPrimitive> postProcess(Changeset cs, ProgressMonitor monitor) {
108 if (monitor == null) {
109 monitor = NullProgressMonitor.INSTANCE;
110 }
111 try {
112 monitor.beginTask("Postprocessing uploaded data ...");
113 monitor.setTicksCount(primitives.size());
114 monitor.setTicks(0);
115 for (IPrimitive p : primitives) {
116 monitor.worked(1);
117 DiffResultEntry entry = diffResults.get(p.getPrimitiveId());
118 if (entry == null) {
119 continue;
120 }
121 processed.add(p);
122 if (!p.isDeleted()) {
123 p.setOsmId(entry.new_id, entry.new_version);
124 p.setVisible(true);
125 } else {
126 p.setVisible(false);
127 }
128 if (cs != null && !cs.isNew()) {
129 p.setChangesetId(cs.getId());
130 }
131 }
132 return processed;
133 } finally {
134 monitor.finishTask();
135 }
136 }
137
138 private class Parser extends DefaultHandler {
139 private Locator locator;
140
141 @Override
142 public void setDocumentLocator(Locator locator) {
143 this.locator = locator;
144 }
145
146 protected void throwException(String msg) throws XmlParsingException {
147 throw new XmlParsingException(msg).rememberLocation(locator);
148 }
149
150 @Override
151 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
152 try {
153 switch (qName) {
154 case "diffResult":
155 // the root element, ignore
156 break;
157 case "node":
158 case "way":
159 case "relation":
160 PrimitiveId id = new SimplePrimitiveId(
161 Long.parseLong(atts.getValue("old_id")),
162 OsmPrimitiveType.fromApiTypeName(qName)
163 );
164 DiffResultEntry entry = new DiffResultEntry();
165 if (atts.getValue("new_id") != null) {
166 entry.new_id = Long.parseLong(atts.getValue("new_id"));
167 }
168 if (atts.getValue("new_version") != null) {
169 entry.new_version = Integer.parseInt(atts.getValue("new_version"));
170 }
171 diffResults.put(id, entry);
172 break;
173 default:
174 throwException(tr("Unexpected XML element with name ''{0}''", qName));
175 }
176 } catch (NumberFormatException e) {
177 throw new XmlParsingException(e).rememberLocation(locator);
178 }
179 }
180 }
181}
Note: See TracBrowser for help on using the repository browser.