001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.io.InputStream; 007import java.util.Arrays; 008 009import javax.xml.stream.XMLStreamConstants; 010import javax.xml.stream.XMLStreamException; 011 012import org.openstreetmap.josm.data.osm.DataSet; 013import org.openstreetmap.josm.data.osm.OsmPrimitive; 014import org.openstreetmap.josm.gui.progress.ProgressMonitor; 015 016public class OsmChangeReader extends OsmReader { 017 018 public static final String[] ACTIONS = {"create", "modify", "delete"}; 019 020 /** 021 * constructor (for private and subclasses use only) 022 * 023 * @see #parseDataSet(InputStream, ProgressMonitor) 024 */ 025 protected OsmChangeReader() { 026 } 027 028 /* (non-Javadoc) 029 * @see org.openstreetmap.josm.io.OsmReader#parseRoot() 030 */ 031 @Override 032 protected void parseRoot() throws XMLStreamException { 033 if (parser.getLocalName().equals("osmChange")) { 034 parseOsmChange(); 035 } else { 036 parseUnknown(); 037 } 038 } 039 040 private void parseOsmChange() throws XMLStreamException { 041 String v = parser.getAttributeValue(null, "version"); 042 if (v == null) { 043 throwException(tr("Missing mandatory attribute ''{0}''.", "version")); 044 } 045 if (!v.equals("0.6")) { 046 throwException(tr("Unsupported version: {0}", v)); 047 } 048 ds.setVersion(v); 049 while (parser.hasNext()) { 050 int event = parser.next(); 051 if (event == XMLStreamConstants.START_ELEMENT) { 052 if (Arrays.asList(ACTIONS).contains(parser.getLocalName())) { 053 parseCommon(parser.getLocalName()); 054 } else { 055 parseUnknown(); 056 } 057 } else if (event == XMLStreamConstants.END_ELEMENT) { 058 return; 059 } 060 } 061 } 062 063 private void parseCommon(String action) throws XMLStreamException { 064 while (parser.hasNext()) { 065 int event = parser.next(); 066 if (event == XMLStreamConstants.START_ELEMENT) { 067 OsmPrimitive p = null; 068 if (parser.getLocalName().equals("node")) { 069 p = parseNode(); 070 } else if (parser.getLocalName().equals("way")) { 071 p = parseWay(); 072 } else if (parser.getLocalName().equals("relation")) { 073 p = parseRelation(); 074 } else { 075 parseUnknown(); 076 } 077 if (p != null && action != null) { 078 if (action.equals("modify")) { 079 p.setModified(true); 080 } else if (action.equals("delete")) { 081 p.setDeleted(true); 082 } 083 } 084 } else if (event == XMLStreamConstants.END_ELEMENT) { 085 return; 086 } 087 } 088 } 089 090 /** 091 * Parse the given input source and return the dataset. 092 * 093 * @param source the source input stream. Must not be <code>null</code>. 094 * @param progressMonitor the progress monitor. If <code>null</code>, 095 * {@link org.openstreetmap.josm.gui.progress.NullProgressMonitor#INSTANCE} is assumed 096 * 097 * @return the dataset with the parsed data 098 * @throws IllegalDataException thrown if the an error was found while parsing the data from the source 099 * @throws IllegalArgumentException thrown if source is <code>null</code> 100 */ 101 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { 102 return new OsmChangeReader().doParseDataSet(source, progressMonitor); 103 } 104}