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 016/** 017 * Reader for <a href="http://wiki.openstreetmap.org/wiki/OsmChange">OsmChange</a> file format. 018 */ 019public class OsmChangeReader extends OsmReader { 020 021 /** 022 * List of possible actions. 023 */ 024 private static final String[] ACTIONS = {"create", "modify", "delete"}; 025 026 /** 027 * constructor (for private and subclasses use only) 028 * 029 * @see #parseDataSet(InputStream, ProgressMonitor) 030 */ 031 protected OsmChangeReader() { 032 // Restricts visibility 033 } 034 035 @Override 036 protected void parseRoot() throws XMLStreamException { 037 if ("osmChange".equals(parser.getLocalName())) { 038 parseOsmChange(); 039 } else { 040 parseUnknown(); 041 } 042 } 043 044 private void parseOsmChange() throws XMLStreamException { 045 String v = parser.getAttributeValue(null, "version"); 046 if (v == null) { 047 throwException(tr("Missing mandatory attribute ''{0}''.", "version")); 048 } 049 if (!"0.6".equals(v)) { 050 throwException(tr("Unsupported version: {0}", v)); 051 } 052 ds.setVersion(v); 053 while (parser.hasNext()) { 054 int event = parser.next(); 055 if (event == XMLStreamConstants.START_ELEMENT) { 056 if (Arrays.asList(ACTIONS).contains(parser.getLocalName())) { 057 parseCommon(parser.getLocalName()); 058 } else { 059 parseUnknown(); 060 } 061 } else if (event == XMLStreamConstants.END_ELEMENT) { 062 return; 063 } 064 } 065 } 066 067 private void parseCommon(String action) throws XMLStreamException { 068 while (parser.hasNext()) { 069 int event = parser.next(); 070 if (event == XMLStreamConstants.START_ELEMENT) { 071 OsmPrimitive p = null; 072 switch (parser.getLocalName()) { 073 case "node": 074 p = parseNode(); 075 break; 076 case "way": 077 p = parseWay(); 078 break; 079 case "relation": 080 p = parseRelation(); 081 break; 082 default: 083 parseUnknown(); 084 } 085 if (p != null && action != null) { 086 if ("modify".equals(action)) { 087 p.setModified(true); 088 } else if ("delete".equals(action)) { 089 p.setDeleted(true); 090 } 091 } 092 } else if (event == XMLStreamConstants.END_ELEMENT) { 093 return; 094 } 095 } 096 } 097 098 /** 099 * Parse the given input source and return the dataset. 100 * 101 * @param source the source input stream. Must not be <code>null</code>. 102 * @param progressMonitor the progress monitor. If <code>null</code>, 103 * {@link org.openstreetmap.josm.gui.progress.NullProgressMonitor#INSTANCE} is assumed 104 * 105 * @return the dataset with the parsed data 106 * @throws IllegalDataException if the an error was found while parsing the data from the source 107 * @throws IllegalArgumentException if source is <code>null</code> 108 */ 109 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { 110 return new OsmChangeReader().doParseDataSet(source, progressMonitor); 111 } 112}