Changeset 2604 in josm
- Timestamp:
- 2009-12-10T18:42:41+01:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 9 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
r2567 r2604 126 126 + "<li>"+tr("<b>user:anonymous</b> - all objects changed by anonymous users")+"</li>" 127 127 + "<li>"+tr("<b>id:</b>... - object with given ID (0 for new objects)")+"</li>" 128 + "<li>"+tr("<b>changeset:</b>... - object with given changeset id (0 objects without assigned changeset)")+"</li>" 128 129 + "<li>"+tr("<b>nodes:</b>... - object with given number of nodes")+"</li>" 129 130 + "<li>"+tr("<b>tags:</b>... - object with given number of tags (tags:count or tags:min-max)")+"</li>" -
trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
r2578 r2604 85 85 } 86 86 @Override public String toString() {return "id="+id;} 87 } 88 89 private static class ChangesetId extends Match { 90 private long changesetid; 91 public ChangesetId(long changesetid) {this.changesetid = changesetid;} 92 @Override public boolean match(OsmPrimitive osm) { 93 return osm.getChangesetId() == changesetid; 94 } 95 @Override public String toString() {return "changeset="+changesetid;} 87 96 } 88 97 … … 693 702 throw new ParseError(tr("Incorrect value of id operator: {0}. Number is expected.", value)); 694 703 } 704 } else if (key.equals("changeset")) { 705 try { 706 return new ChangesetId(Integer.parseInt(value)); 707 } catch (NumberFormatException x) { 708 throw new ParseError(tr("Incorrect value of changeset operator: {0}. Number is expected.", value)); 709 } 695 710 } else 696 711 return new KeyValue(key, value, regexSearch, caseSensitive); -
trunk/src/org/openstreetmap/josm/data/osm/Changeset.java
r2598 r2604 17 17 public final class Changeset implements Tagged { 18 18 /** the changeset id */ 19 private longid;19 private int id; 20 20 /** the user who owns the changeset */ 21 21 private User user; … … 50 50 * @param id the id 51 51 */ 52 public Changeset( longid) {52 public Changeset(int id) { 53 53 this.id = id; 54 54 this.incomplete = id > 0; … … 90 90 91 91 public int compareTo(Changeset other) { 92 return Long.valueOf(getId()).compareTo(other.getId());92 return Integer.valueOf(getId()).compareTo(other.getId()); 93 93 } 94 94 … … 102 102 } 103 103 104 public longgetId() {104 public int getId() { 105 105 return id; 106 106 } 107 107 108 public void setId( longid) {108 public void setId(int id) { 109 109 this.id = id; 110 110 } … … 234 234 final int prime = 31; 235 235 int result = 1; 236 result = prime * result + (i nt) (id ^ (id >>> 32));236 result = prime * result + (id ^ (id >>> 32)); 237 237 if (id > 0) 238 238 return prime * result + getClass().hashCode(); … … 306 306 return id <= 0; 307 307 } 308 309 public void mergeFrom(Changeset other) { 310 if (other == null) 311 return; 312 if (id != other.id) 313 return; 314 this.user = other.user; 315 this.createdAt = other.createdAt; 316 this.closedAt = other.closedAt; 317 this.open = other.open; 318 this.min = other.min; 319 this.max = other.max; 320 this.tags.clear(); 321 this.tags.putAll(other.tags); 322 } 308 323 } -
trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
r2603 r2604 238 238 239 239 /** 240 * The id of the changeset this primitive was last uploaded to. 241 * 0 if it wasn't uploaded to a changeset yet of if the changeset 242 * id isn't known. 243 */ 244 private int changesetId; 245 246 /** 240 247 * Creates a new primitive for the given id. If the id > 0, the primitive is marked 241 248 * as incomplete. … … 577 584 public void setUser(User user) { 578 585 this.user = user; 586 } 587 588 589 /** 590 * Replies the id of the changeset this primitive was last uploaded to. 591 * 0 if this primitive wasn't uploaded to a changeset yet or if the 592 * changeset isn't known. 593 * 594 * @return the id of the changeset this primitive was last uploaded to. 595 */ 596 public int getChangesetId() { 597 return changesetId; 598 } 599 600 601 /** 602 * Sets the changeset id of this primitive. Can't be set on a new 603 * primitive. 604 * 605 * @param changesetId the id. >= 0 required. 606 * @throws IllegalStateException thrown if this primitive is new. 607 * @throws IllegalArgumentException thrown if id < 0 608 */ 609 public void setChangesetId(int changesetId) throws IllegalStateException, IllegalArgumentException { 610 if (changesetId < 0) 611 throw new IllegalArgumentException(tr("Parameter ''{0}'' >= 0 expected, got {1}", "changesetId", changesetId)); 612 if (isNew() && changesetId > 0) 613 throw new IllegalStateException(tr("Can''t assign a changesetId > 0 to a new primitive. Value of changesetId is {0}", changesetId)); 614 this.changesetId = changesetId; 579 615 } 580 616 … … 916 952 * use this only in the data initializing phase 917 953 */ 918 public void cloneFrom(OsmPrimitive osm) { 919 setKeys(osm.getKeys()); 920 id = osm.id; 921 timestamp = osm.timestamp; 922 version = osm.version; 923 setIncomplete(osm.isIncomplete()); 924 flags = osm.flags; 925 user= osm.user; 954 public void cloneFrom(OsmPrimitive other) { 955 setKeys(other.getKeys()); 956 id = other.id; 957 timestamp = other.timestamp; 958 version = other.version; 959 setIncomplete(other.isIncomplete()); 960 flags = other.flags; 961 user= other.user; 962 changesetId = other.changesetId; 926 963 clearCached(); 927 964 } … … 951 988 flags = other.flags; 952 989 user= other.user; 990 changesetId = other.changesetId; 953 991 } 954 992 … … 1000 1038 && version == other.version 1001 1039 && isVisible() == other.isVisible() 1002 && (user == null ? other.user==null : user==other.user); 1040 && (user == null ? other.user==null : user==other.user) 1041 && changesetId == other.changesetId; 1003 1042 } 1004 1043 … … 1098 1137 timestamp = data.getTimestamp(); 1099 1138 user = data.getUser(); 1139 changesetId = data.getChangesetId(); 1100 1140 setDeleted(data.isDeleted()); 1101 1141 setModified(data.isModified()); … … 1118 1158 data.setModified(isModified()); 1119 1159 data.setVisible(isVisible()); 1160 data.setChangesetId(changesetId); 1120 1161 } 1121 1162 -
trunk/src/org/openstreetmap/josm/data/osm/PrimitiveData.java
r2598 r2604 46 46 private int version; 47 47 private int timestamp; 48 private int changesetId; 48 49 49 50 public boolean isModified() { … … 89 90 this.timestamp = timestamp; 90 91 } 92 93 public int getChangesetId() { 94 return changesetId; 95 } 96 97 public void setChangesetId(int changesetId) { 98 this.changesetId = changesetId; 99 } 100 91 101 public Map<String, String> getKeys() { 92 102 return keys; -
trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java
r2600 r2604 7 7 import java.io.StringReader; 8 8 import java.util.Collection; 9 import java.util.Collections; 9 10 import java.util.HashMap; 11 import java.util.HashSet; 10 12 import java.util.Map; 13 import java.util.Set; 11 14 12 15 import javax.xml.parsers.ParserConfigurationException; 13 16 import javax.xml.parsers.SAXParserFactory; 14 17 15 import org.openstreetmap.josm.data.osm. Node;18 import org.openstreetmap.josm.data.osm.Changeset; 16 19 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 import org.openstreetmap.josm.data.osm.Relation; 18 import org.openstreetmap.josm.data.osm.Way; 19 import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor; 20 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 21 import org.openstreetmap.josm.data.osm.PrimitiveId; 22 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 23 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 20 24 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 21 25 import org.xml.sax.Attributes; 22 26 import org.xml.sax.InputSource; 27 import org.xml.sax.Locator; 23 28 import org.xml.sax.SAXException; 24 29 import org.xml.sax.helpers.DefaultHandler; 25 30 26 /** 27 */ 28 public class DiffResultReader extends AbstractVisitor { 31 public class DiffResultProcessor { 29 32 30 /** 31 * mapping from old id to new id/version 32 */ 33 private Map<String, Long[]> versions = new HashMap<String, Long[]>(); 34 private Collection<OsmPrimitive> processed; 35 private Map<OsmPrimitive,Long> newIdMap; 36 37 /** 38 * List of protocol versions that will be accepted on reading 39 */ 40 41 private class Parser extends DefaultHandler { 42 43 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 44 try { 45 if (qName.equals("osm")) { 46 } else if (qName.equals("node") || qName.equals("way") || qName.equals("relation")) { 47 String key = qName + ":" + atts.getValue("old_id"); 48 String newid = atts.getValue("new_id"); 49 String newver = atts.getValue("new_version"); 50 Long[] value = new Long[] { newid == null ? null : new Long(newid), newver == null ? null : new Long(newver) }; 51 versions.put(key, value); 52 } 53 } catch (NumberFormatException x) { 54 x.printStackTrace(); // SAXException does not chain correctly 55 throw new SAXException(x.getMessage(), x); 56 } catch (NullPointerException x) { 57 x.printStackTrace(); // SAXException does not chain correctly 58 throw new SAXException(tr("NullPointerException, possibly some missing tags."), x); 59 } 60 } 33 static private class DiffResultEntry { 34 public long new_id; 35 public int new_version; 61 36 } 62 37 63 38 /** 64 * Parse the given input source and return the dataset. 39 * mapping from old id to new id and version, the result of parsing the diff result 40 * replied by the server 65 41 */ 66 public static void parseDiffResult(String source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, ProgressMonitor progressMonitor) 67 throws SAXException, IOException { 42 private Map<PrimitiveId, DiffResultEntry> diffResults = new HashMap<PrimitiveId, DiffResultEntry>(); 43 /** 44 * the set of processed primitives *after* the new id, the new version and the new changeset id 45 * is set 46 */ 47 private Set<OsmPrimitive> processed; 48 /** 49 * the collection of primitives being uploaded 50 */ 51 private Collection<OsmPrimitive> primitives; 68 52 69 progressMonitor.beginTask(tr("Preparing data...")); 53 /** 54 * Creates a diff result reader 55 * 56 * @param primitives the collection of primitives which have been uploaded. If null, 57 * assumes an empty collection. 58 */ 59 public DiffResultProcessor(Collection<OsmPrimitive> primitives) { 60 if (primitives == null) { 61 primitives = Collections.emptyList(); 62 } 63 this.primitives = primitives; 64 this.processed = new HashSet<OsmPrimitive>(); 65 } 66 67 /** 68 * Parse the response from a diff upload to the OSM API. 69 * 70 * @param diffUploadResponse the response. Must not be null. 71 * @param progressMonitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null 72 * @throws IllegalArgumentException thrown if diffUploadRequest is null 73 * @throws OsmDataParsingException thrown if the diffUploadRequest can't be parsed successfully 74 * 75 */ 76 public void parse(String diffUploadResponse, ProgressMonitor progressMonitor) throws OsmDataParsingException { 77 if (progressMonitor == null) { 78 progressMonitor = NullProgressMonitor.INSTANCE; 79 } 80 if (diffUploadResponse == null) 81 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "source")); 70 82 try { 71 72 DiffResultReader drr = new DiffResultReader(); 73 drr.processed = processed; 74 drr.newIdMap = newIdMap; 75 InputSource inputSource = new InputSource(new StringReader(source)); 76 try { 77 SAXParserFactory.newInstance().newSAXParser().parse(inputSource, drr.new Parser()); 78 } catch (ParserConfigurationException e1) { 79 e1.printStackTrace(); // broken SAXException chaining 80 throw new SAXException(e1); 81 } 82 83 for (OsmPrimitive p : osm) { 84 //System.out.println("old: "+ p); 85 p.visit(drr); 86 //System.out.println("new: "+ p); 87 //System.out.println(""); 88 } 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); 89 94 } finally { 90 95 progressMonitor.finishTask(); … … 92 97 } 93 98 94 public void visit(Node n) { 95 String key = "node:" + (newIdMap.containsKey(n) ? newIdMap.get(n) : n.getId()); 96 Long[] nv = versions.get(key); 97 if (nv != null) { 98 processed.add(n); 99 if (!n.isDeleted()) { 100 n.setOsmId(nv[0], nv[1].intValue()); 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 } 128 if (cs != null && !cs.isNew()) { 129 p.setChangesetId(cs.getId()); 130 } 101 131 } 132 return processed; 133 } finally { 134 monitor.finishTask(); 102 135 } 103 136 } 104 public void visit(Way w) { 105 String key = "way:" + (newIdMap.containsKey(w) ? newIdMap.get(w) : w.getId()); 106 Long[] nv = versions.get(key); 107 if (nv != null) { 108 processed.add(w); 109 if (!w.isDeleted()) { 110 w.setOsmId(nv[0], nv[1].intValue()); 111 } 137 138 private class Parser extends DefaultHandler { 139 private Locator locator; 140 141 @Override 142 public void setDocumentLocator(Locator locator) { 143 this.locator = locator; 112 144 } 113 } 114 public void visit(Relation r) { 115 String key = "relation:" + (newIdMap.containsKey(r) ? newIdMap.get(r) : r.getId()); 116 Long[] nv = versions.get(key); 117 if (nv != null) { 118 processed.add(r); 119 if (!r.isDeleted()) { 120 r.setOsmId(nv[0], nv[1].intValue()); 145 146 protected void throwException(String msg) throws OsmDataParsingException{ 147 throw new OsmDataParsingException(msg).rememberLocation(locator); 148 } 149 150 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 151 try { 152 if (qName.equals("diffResult")) { 153 // the root element, ignore 154 } else if (qName.equals("node") || qName.equals("way") || qName.equals("relation")) { 155 156 PrimitiveId id = new SimplePrimitiveId( 157 Long.parseLong(atts.getValue("old_id")), 158 OsmPrimitiveType.fromApiTypeName(qName) 159 ); 160 DiffResultEntry entry = new DiffResultEntry(); 161 if (atts.getValue("new_id") != null) { 162 entry.new_id = Long.parseLong(atts.getValue("new_id")); 163 } 164 if (atts.getValue("new_version") != null) { 165 entry.new_version = Integer.parseInt(atts.getValue("new_version")); 166 } 167 diffResults.put(id, entry); 168 } else { 169 throwException(tr("Unexpected XML element with name ''{0}''", qName)); 170 } 171 } catch (NumberFormatException e) { 172 throw new OsmDataParsingException(e).rememberLocation(locator); 121 173 } 122 174 } -
trunk/src/org/openstreetmap/josm/io/OsmApi.java
r2599 r2604 19 19 import java.net.URL; 20 20 import java.net.UnknownHostException; 21 import java.util.ArrayList;22 21 import java.util.Collection; 23 22 import java.util.Collections; … … 30 29 import org.openstreetmap.josm.data.osm.OsmPrimitive; 31 30 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 32 import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor;33 31 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 34 32 import org.openstreetmap.josm.gui.progress.ProgressMonitor; … … 240 238 ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/create", toXml(osm, true),monitor); 241 239 osm.setOsmId(Long.parseLong(ret.trim()), 1); 240 osm.setChangesetId(getChangeset().getId()); 242 241 } catch(NumberFormatException e){ 243 242 throw new OsmTransferException(tr("Unexpected format of ID replied by the server. Got ''{0}''.", ret)); … … 260 259 ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.getId(), toXml(osm, true), monitor); 261 260 osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim())); 261 osm.setChangesetId(getChangeset().getId()); 262 262 } catch(NumberFormatException e) { 263 263 throw new OsmTransferException(tr("Unexpected format of new version of modified primitive ''{0}''. Got ''{1}''.", osm.getId(), ret)); … … 301 301 try { 302 302 ret = sendRequest("PUT", "changeset/create", toXml(changeset),progressMonitor); 303 changeset.setId( Long.parseLong(ret.trim()));303 changeset.setId(Integer.parseInt(ret.trim())); 304 304 changeset.setOpen(true); 305 305 } catch(NumberFormatException e){ … … 398 398 399 399 initialize(monitor); 400 final ArrayList<OsmPrimitive> processed = new ArrayList<OsmPrimitive>(); 401 402 CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, OsmApi.this); 403 404 monitor.subTask(tr("Preparing...")); 405 for (OsmPrimitive osm : list) { 406 osm.visit(duv); 407 monitor.worked(1); 408 } 409 monitor.indeterminateSubTask(tr("Uploading...")); 410 411 String diff = duv.getDocument(); 412 String diffresult = sendRequest("POST", "changeset/" + changeset.getId() + "/upload", diff,monitor); 413 DiffResultReader.parseDiffResult(diffresult, list, processed, duv.getNewIdMap(), 414 monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 415 return processed; 400 401 // prepare upload request 402 // 403 OsmChangeBuilder changeBuilder = new OsmChangeBuilder(changeset); 404 monitor.subTask(tr("Preparing upload request...")); 405 changeBuilder.start(); 406 changeBuilder.append(list); 407 changeBuilder.finish(); 408 String diffUploadRequest = changeBuilder.getDocument(); 409 410 // Upload to the server 411 // 412 monitor.indeterminateSubTask(tr("Uploading {0} objects...", list.size())); 413 String diffUploadResponse = sendRequest("POST", "changeset/" + changeset.getId() + "/upload", diffUploadRequest,monitor); 414 415 // Process the response from the server 416 // 417 DiffResultProcessor reader = new DiffResultProcessor(list); 418 reader.parse(diffUploadResponse, monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); 419 return reader.postProcess( 420 getChangeset(), 421 monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false) 422 ); 416 423 } catch(OsmTransferException e) { 417 424 throw e; 418 } catch( Exception e) {425 } catch(OsmDataParsingException e) { 419 426 throw new OsmTransferException(e); 420 427 } finally { -
trunk/src/org/openstreetmap/josm/io/OsmChangeBuilder.java
r2600 r2604 1 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.data.osm.visitor; 2 package org.openstreetmap.josm.io; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 3 5 4 6 import java.io.PrintWriter; 5 7 import java.io.StringWriter; 6 import java.util. Map;8 import java.util.Collection; 7 9 8 10 import org.openstreetmap.josm.data.osm.Changeset; 9 import org.openstreetmap.josm.data.osm.Node;10 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 11 import org.openstreetmap.josm.data.osm.Relation;12 import org.openstreetmap.josm.data.osm.Way;13 import org.openstreetmap.josm.io.OsmApi;14 import org.openstreetmap.josm.io.OsmWriter;15 12 16 13 /** … … 19 16 * OsmChange format. 20 17 * 21 * @author fred22 *23 18 */ 24 public class CreateOsmChangeVisitor extends AbstractVisitor { 19 public class OsmChangeBuilder { 20 static public final String DEFAULT_API_VERSION = "0.6"; 25 21 26 22 private String currentMode; … … 28 24 private StringWriter swriter; 29 25 private OsmWriter osmwriter; 30 private OsmApi api; 26 private String apiVersion = DEFAULT_API_VERSION; 27 private boolean prologWritten = false; 31 28 32 public CreateOsmChangeVisitor(Changeset changeset, OsmApi api) { 29 public OsmChangeBuilder(Changeset changeset) { 30 this(changeset, null /* default api version */); 31 } 32 33 public OsmChangeBuilder(Changeset changeset, String apiVersion) { 34 this.apiVersion = apiVersion == null ? DEFAULT_API_VERSION : apiVersion; 33 35 writer = new PrintWriter(swriter = new StringWriter()); 34 writer.write("<osmChange version=\""); 35 writer.write(api.getVersion()); 36 writer.write("\" generator=\"JOSM\">\n"); 37 this.api = api; 38 // need to set osmConform = false here so that negative IDs get transmitted. 39 // this also enables unnecessary and (if the API were more strict) potentially 40 // harmful action="..." attributes. 41 osmwriter = new OsmWriter(writer, false, api.getVersion()); 36 osmwriter = new OsmWriter(writer, false, apiVersion); 42 37 osmwriter.setChangeset(changeset); 43 38 } 44 39 45 // FIXME: This should really NOT use a visitor pattern, it looks 46 // stupid. Just have one method named "write" instead of three "visit"s. 47 48 public void visit(Node n) { 49 if (n.isDeleted()) { 40 protected void write(OsmPrimitive p) { 41 if (p.isDeleted()) { 50 42 switchMode("delete"); 51 43 osmwriter.setWithBody(false); 52 osmwriter.visit(n);44 p.visit(osmwriter); 53 45 } else { 54 switchMode( n.isNew() ? "create" : "modify");46 switchMode(p.isNew() ? "create" : "modify"); 55 47 osmwriter.setWithBody(true); 56 osmwriter.visit(n); 57 } 58 } 59 public void visit(Way w) { 60 if (w.isDeleted()) { 61 switchMode("delete"); 62 osmwriter.setWithBody(false); 63 osmwriter.visit(w); 64 } else { 65 switchMode(w.isNew() ? "create" : "modify"); 66 osmwriter.setWithBody(true); 67 osmwriter.visit(w); 68 } 69 } 70 public void visit(Relation r) { 71 if (r.isDeleted()) { 72 switchMode("delete"); 73 osmwriter.setWithBody(false); 74 osmwriter.visit(r); 75 } else { 76 switchMode(r.isNew() ? "create" : "modify"); 77 osmwriter.setWithBody(true); 78 osmwriter.visit(r); 48 p.visit(osmwriter); 79 49 } 80 50 } … … 83 53 if ((newMode != null && !newMode.equals(currentMode))||(newMode == null && currentMode != null)) { 84 54 if (currentMode != null) { 85 writer. write("</");86 writer. write(currentMode);87 writer. write(">\n");55 writer.print("</"); 56 writer.print(currentMode); 57 writer.println(">"); 88 58 } 89 59 if (newMode != null) { 90 writer.write("<"); 91 writer.write(newMode); 92 writer.write(" version=\""); 93 writer.write(api.getVersion()); 94 writer.write("\" generator=\"JOSM\">\n"); 60 writer.print("<"); 61 writer.print(newMode); 62 writer.println(">"); 95 63 } 96 64 currentMode = newMode; … … 98 66 } 99 67 100 public String getDocument() { 101 switchMode(null); 102 return swriter.toString() + "</osmChange>\n"; 68 /** 69 * Writes the prolog of the OsmChange document 70 * 71 * @throws IllegalStateException thrown if the prologs has already been written 72 */ 73 public void start() throws IllegalStateException{ 74 if (prologWritten) 75 throw new IllegalStateException(tr("Prolog of OsmChange document already written. Please write only once.")); 76 writer.print("<osmChange version=\""); 77 writer.print(apiVersion); 78 writer.println("\" generator=\"JOSM\">"); 79 prologWritten=true; 103 80 } 104 81 105 public Map<OsmPrimitive,Long> getNewIdMap() { 106 return osmwriter.usedNewIds; 82 /** 83 * Appends a collection of {@see OsmPrimitive}s to the OsmChange document. 84 * 85 * @param primitives the collection of primitives. Ignored if null. 86 * @throws IllegalStateException thrown if the prologs has not been written yet 87 * @see #start() 88 * @see #append(OsmPrimitive) 89 */ 90 public void append(Collection<OsmPrimitive> primitives) throws IllegalStateException{ 91 if (primitives == null) return; 92 if (!prologWritten) 93 throw new IllegalStateException(tr("Prolog of OsmChange document not written yet. Please write frst.")); 94 for (OsmPrimitive p : primitives) { 95 write(p); 96 } 97 } 98 99 /** 100 * Appends an {@see OsmPrimitive} to the OsmChange document. 101 * 102 * @param p the primitive. Ignored if null. 103 * @throws IllegalStateException thrown if the prologs has not been written yet 104 * @see #start() 105 * @see #append(Collection) 106 107 */ 108 public void append(OsmPrimitive p) { 109 if (p == null) return; 110 if (!prologWritten) 111 throw new IllegalStateException(tr("Prolog of OsmChange document not written yet. Please write frst.")); 112 write(p); 113 } 114 115 /** 116 * Writes the epilog of the OsmChange document 117 * 118 * @throws IllegalStateException thrown if the prologs has not been written yet 119 */ 120 public void finish() throws IllegalStateException { 121 if (!prologWritten) 122 throw new IllegalStateException(tr("Prolog of OsmChange document not written yet. Please write frst.")); 123 if (currentMode != null) { 124 writer.print("</"); 125 writer.print(currentMode); 126 writer.println(">"); 127 } 128 writer.println("</osmChange>"); 129 } 130 131 public String getDocument() { 132 return swriter.toString(); 107 133 } 108 134 } -
trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java
r2512 r2604 72 72 throwException(tr("Missing mandatory attribute ''{0}''.", "id")); 73 73 } 74 longid = 0;74 int id = 0; 75 75 try { 76 id = Long.parseLong(value);76 id = Integer.parseInt(value); 77 77 } catch(NumberFormatException e) { 78 78 throwException(tr("Illegal value for attribute ''{0}''. Got ''{1}''.", "id", value)); -
trunk/src/org/openstreetmap/josm/io/OsmReader.java
r2591 r2604 25 25 import org.openstreetmap.josm.data.osm.OsmPrimitive; 26 26 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 27 import org.openstreetmap.josm.data.osm.PrimitiveId; 27 28 import org.openstreetmap.josm.data.osm.Relation; 28 29 import org.openstreetmap.josm.data.osm.RelationMember; 30 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 29 31 import org.openstreetmap.josm.data.osm.User; 30 32 import org.openstreetmap.josm.data.osm.Way; 33 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 31 34 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 32 35 import org.openstreetmap.josm.tools.DateUtils; … … 69 72 * </ul> 70 73 */ 71 private Map< String, OsmPrimitive> externalIdMap = new HashMap<String, OsmPrimitive>();74 private Map<PrimitiveId, OsmPrimitive> externalIdMap = new HashMap<PrimitiveId, OsmPrimitive>(); 72 75 73 76 /** … … 78 81 */ 79 82 private OsmReader() { 80 externalIdMap = new HashMap< String, OsmPrimitive>();83 externalIdMap = new HashMap<PrimitiveId, OsmPrimitive>(); 81 84 } 82 85 … … 91 94 public LatLon latlon = new LatLon(0,0); 92 95 private OsmPrimitive primitive; 96 private int changesetId; 93 97 94 98 public void copyTo(OsmPrimitive osm) { … … 101 105 osm.setTimestamp(timestamp); 102 106 osm.setUser(user); 103 if (id > 0) { 107 if (!osm.isNew() && changesetId > 0) { 108 osm.setChangesetId(changesetId); 109 } else if (osm.isNew() && changesetId > 0) { 110 System.out.println(tr("Warning: ignoring changeset id {0} for new object with external id {1} and internal id {2}", 111 changesetId, 112 id, 113 osm.getUniqueId() 114 )); 115 } 116 if (! osm.isNew()) { 104 117 // ignore visible attribute for objects not yet known to the server 105 118 // … … 218 231 readCommon(atts, current); 219 232 Node n = current.createNode(); 220 externalIdMap.put( "n"+current.id, n);233 externalIdMap.put(new SimplePrimitiveId(current.id, OsmPrimitiveType.NODE), n); 221 234 } else if (qName.equals("way")) { 222 235 current = new OsmPrimitiveData(); 223 236 readCommon(atts, current); 224 237 Way w = current.createWay(); 225 externalIdMap.put( "w"+current.id, w);238 externalIdMap.put(new SimplePrimitiveId(current.id, OsmPrimitiveType.WAY), w); 226 239 ways.put(current.id, new ArrayList<Long>()); 227 240 } else if (qName.equals("nd")) { … … 251 264 readCommon(atts, current); 252 265 Relation r = current.createRelation(); 253 externalIdMap.put( "r"+current.id, r);266 externalIdMap.put(new SimplePrimitiveId(current.id, OsmPrimitiveType.RELATION), r); 254 267 relations.put(current.id, new LinkedList<RelationMemberData>()); 255 268 } else if (qName.equals("member")) { … … 386 399 387 400 String action = atts.getValue("action"); 388 if (action == null) 389 return;390 if (action.equals("delete")) {401 if (action == null) { 402 // do nothing 403 } else if (action.equals("delete")) { 391 404 current.deleted = true; 392 } else if (action.startsWith("modify")) { 405 } else if (action.startsWith("modify")) { //FIXME: why startsWith()? why not equals()? 393 406 current.modified = true; 407 } 408 409 String v = atts.getValue("changeset"); 410 if (v == null) { 411 current.changesetId = 0; 412 } else { 413 try { 414 current.changesetId = Integer.parseInt(v); 415 } catch(NumberFormatException e) { 416 if (current.id <= 0) { 417 // for a new primitive we just log a warning 418 System.out.println(tr("Illegal value for attribute ''changeset'' on new object {1}. Got {0}. Resetting to 0.", v, current.id)); 419 current.changesetId = 0; 420 } else { 421 // for an existing primitive this is a problem 422 throwException(tr("Illegal value for attribute ''changeset''. Got {0}.", v)); 423 } 424 } 425 if (current.changesetId <=0) { 426 if (current.id <= 0) { 427 // for a new primitive we just log a warning 428 System.out.println(tr("Illegal value for attribute ''changeset'' on new object {1}. Got {0}. Resetting to 0.", v, current.id)); 429 current.changesetId = 0; 430 } else { 431 // for an existing primitive this is a problem 432 throwException(tr("Illegal value for attribute ''changeset''. Got {0}.", v)); 433 } 434 } 394 435 } 395 436 } … … 417 458 protected void processWaysAfterParsing() throws IllegalDataException{ 418 459 for (Long externalWayId: ways.keySet()) { 419 Way w = (Way)externalIdMap.get( "w" + externalWayId);460 Way w = (Way)externalIdMap.get(new SimplePrimitiveId(externalWayId, OsmPrimitiveType.WAY)); 420 461 List<Node> wayNodes = new ArrayList<Node>(); 421 462 for (long id : ways.get(externalWayId)) { 422 Node n = (Node)externalIdMap.get( "n" +id);463 Node n = (Node)externalIdMap.get(new SimplePrimitiveId(id, OsmPrimitiveType.NODE)); 423 464 if (n == null) { 424 465 if (id <= 0) … … 476 517 private void processRelationsAfterParsing() throws IllegalDataException { 477 518 for (Long externalRelationId : relations.keySet()) { 478 Relation relation = (Relation) externalIdMap.get("r" +externalRelationId); 519 Relation relation = (Relation) externalIdMap.get( 520 new SimplePrimitiveId(externalRelationId, OsmPrimitiveType.RELATION) 521 ); 479 522 List<RelationMember> relationMembers = new ArrayList<RelationMember>(); 480 523 for (RelationMemberData rm : relations.get(externalRelationId)) { … … 483 526 // lookup the member from the map of already created primitives 484 527 // 485 if (rm.type.equals("node")) { 486 primitive = externalIdMap.get("n" + rm.id); 487 } else if (rm.type.equals("way")) { 488 primitive = externalIdMap.get("w" + rm.id); 489 } else if (rm.type.equals("relation")) { 490 primitive = externalIdMap.get("r" + rm.id); 491 } else 528 try { 529 OsmPrimitiveType type = OsmPrimitiveType.fromApiTypeName(rm.type); 530 primitive = externalIdMap.get(new SimplePrimitiveId(rm.id, type)); 531 } catch(IllegalArgumentException e) { 492 532 throw new IllegalDataException( 493 533 tr("Unknown relation member type ''{0}'' in relation with external id ''{1}''.", rm.type,externalRelationId) 494 534 ); 535 } 495 536 496 537 if (primitive == null) { … … 523 564 } 524 565 ds.addPrimitive(primitive); 525 526 if (rm.type.equals("node")) { 527 externalIdMap.put("n" + rm.id, primitive); 528 } else if (rm.type.equals("way")) { 529 externalIdMap.put("w" + rm.id, primitive); 530 } else if (rm.type.equals("relation")) { 531 externalIdMap.put("r" + rm.id, primitive); 532 } 533 566 externalIdMap.put(new SimplePrimitiveId(rm.id, OsmPrimitiveType.fromApiTypeName(rm.type)), primitive); 534 567 } 535 568 relationMembers.add(new RelationMember(rm.role, primitive)); … … 543 576 * Parse the given input source and return the dataset. 544 577 * 545 * @param source the source input stream 546 * @param progressMonitor the progress monitor 578 * @param source the source input stream. Must not be null. 579 * @param progressMonitor the progress monitor. If null, {@see NullProgressMonitor#INSTANCE} is assumed 547 580 * 548 581 * @return the dataset with the parsed data 549 582 * @throws IllegalDataException thrown if the an error was found while parsing the data from the source 583 * @throws IllegalArgumentException thrown if source is null 550 584 */ 551 585 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { 586 if (progressMonitor == null) { 587 progressMonitor = NullProgressMonitor.INSTANCE; 588 } 589 if (source == null) 590 throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "source")); 552 591 OsmReader reader = new OsmReader(); 553 592 try { -
trunk/src/org/openstreetmap/josm/io/OsmWriter.java
r2578 r2604 2 2 package org.openstreetmap.josm.io; 3 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 4 6 import java.io.PrintWriter; 5 import java.util.HashMap;6 7 import java.util.Map.Entry; 7 8 … … 29 30 public final String DEFAULT_API_VERSION = "0.6"; 30 31 31 /**32 * The counter for newly created objects. Starts at -1 and goes down.33 */34 private long newIdCounter = -1;35 36 /**37 * All newly created ids and their primitive that uses it. This is a back reference38 * map to allow references to use the correnct primitives.39 */40 public HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();41 42 32 private boolean osmConform; 43 33 private boolean withBody = true; … … 123 113 out.println(">"); 124 114 for (Node n : w.getNodes()) { 125 out.println(" <nd ref='"+ getUsedId(n)+"' />");115 out.println(" <nd ref='"+n.getUniqueId()+"' />"); 126 116 } 127 117 addTags(w, "way", false); … … 139 129 out.print(" <member type='"); 140 130 out.print(OsmPrimitiveType.from(em.getMember()).getAPIName()); 141 out.println("' ref='"+ getUsedId(em.getMember())+"' role='" +131 out.println("' ref='"+em.getMember().getUniqueId()+"' role='" + 142 132 XmlWriter.encode(em.getRole()) + "' />"); 143 133 } … … 172 162 } 173 163 174 /**175 * Return the id for the given osm primitive (may access the usedId map)176 */177 private long getUsedId(OsmPrimitive osm) {178 if (!osm.isNew())179 return osm.getId();180 if (usedNewIds.containsKey(osm))181 return usedNewIds.get(osm);182 usedNewIds.put(osm, newIdCounter);183 return osmConform ? 0 : newIdCounter--;184 }185 186 164 private void addTags(Tagged osm, String tagname, boolean tagOpen) { 187 165 if (osm.hasKeys()) { … … 208 186 */ 209 187 private void addCommon(OsmPrimitive osm, String tagname) { 210 long id = getUsedId(osm);211 188 out.print(" <"+tagname); 212 if (id != 0) { 213 out.print(" id='"+getUsedId(osm)+"'"); 214 } 189 if (osm.getUniqueId() != 0) { 190 out.print(" id='"+ osm.getUniqueId()+"'"); 191 } else 192 throw new IllegalStateException(tr("Unexpected id 0 for osm primitive found")); 215 193 if (!osmConform) { 216 194 String action = null; … … 243 221 if (this.changeset != null && this.changeset.getId() != 0) { 244 222 out.print(" changeset='"+this.changeset.getId()+"'" ); 223 } else if (osm.getChangesetId() > 0 && !osm.isNew()) { 224 out.print(" changeset='"+osm.getChangesetId()+"'" ); 245 225 } 246 226 }
Note:
See TracChangeset
for help on using the changeset viewer.