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

Last change on this file since 3718 was 3422, checked in by stoecker, 14 years ago

fix #4401 - upload error - patch by Upliner

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