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

Last change on this file since 3408 was 3336, checked in by stoecker, 14 years ago

#close #5135 - allow undeleting without recreating object - patch by Upliner

  • Property svn:eol-style set to native
File size: 6.7 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 }
129 if (cs != null && !cs.isNew()) {
130 p.setChangesetId(cs.getId());
131 }
132 }
133 return processed;
134 } finally {
135 monitor.finishTask();
136 }
137 }
138
139 private class Parser extends DefaultHandler {
140 private Locator locator;
141
142 @Override
143 public void setDocumentLocator(Locator locator) {
144 this.locator = locator;
145 }
146
147 protected void throwException(String msg) throws OsmDataParsingException{
148 throw new OsmDataParsingException(msg).rememberLocation(locator);
149 }
150
151 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
152 try {
153 if (qName.equals("diffResult")) {
154 // the root element, ignore
155 } else if (qName.equals("node") || qName.equals("way") || qName.equals("relation")) {
156
157 PrimitiveId id = new SimplePrimitiveId(
158 Long.parseLong(atts.getValue("old_id")),
159 OsmPrimitiveType.fromApiTypeName(qName)
160 );
161 DiffResultEntry entry = new DiffResultEntry();
162 if (atts.getValue("new_id") != null) {
163 entry.new_id = Long.parseLong(atts.getValue("new_id"));
164 }
165 if (atts.getValue("new_version") != null) {
166 entry.new_version = Integer.parseInt(atts.getValue("new_version"));
167 }
168 diffResults.put(id, entry);
169 } else {
170 throwException(tr("Unexpected XML element with name ''{0}''", qName));
171 }
172 } catch (NumberFormatException e) {
173 throw new OsmDataParsingException(e).rememberLocation(locator);
174 }
175 }
176 }
177}
Note: See TracBrowser for help on using the repository browser.