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