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 }