source: josm/trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java@ 2667

Last change on this file since 2667 was 2512, checked in by stoecker, 14 years ago

i18n updated, fixed files to reduce problems when applying patches, fix #4017

File size: 10.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.io.InputStream;
8import java.io.InputStreamReader;
9import java.util.Date;
10
11import javax.xml.parsers.ParserConfigurationException;
12import javax.xml.parsers.SAXParserFactory;
13
14import org.openstreetmap.josm.data.coor.LatLon;
15import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
16import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
17import org.openstreetmap.josm.data.osm.history.HistoryNode;
18import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
19import org.openstreetmap.josm.data.osm.history.HistoryRelation;
20import org.openstreetmap.josm.data.osm.history.HistoryWay;
21import org.openstreetmap.josm.gui.progress.ProgressMonitor;
22import org.openstreetmap.josm.tools.DateUtils;
23import org.xml.sax.Attributes;
24import org.xml.sax.InputSource;
25import org.xml.sax.Locator;
26import org.xml.sax.SAXException;
27import org.xml.sax.helpers.DefaultHandler;
28
29/**
30 * Parser for OSM history data.
31 *
32 * It is slightly different from {@see OsmReader} because we don't build an internal graph of
33 * {@see OsmPrimitive}s. We use objects derived from {@see HistoryOsmPrimitive} instead and we
34 * keep the data in a dedicated {@see HistoryDataSet}.
35 *
36 */
37public class OsmHistoryReader {
38
39 private InputStream in;
40 private HistoryDataSet data;
41
42 private class Parser extends DefaultHandler {
43
44 /** the current primitive to be read */
45 private HistoryOsmPrimitive current;
46 private Locator locator;
47
48 @Override
49 public void setDocumentLocator(Locator locator) {
50 this.locator = locator;
51 }
52
53 protected String getCurrentPosition() {
54 if (locator == null)
55 return "";
56 return "(" + locator.getLineNumber() + "," + locator.getColumnNumber() + ")";
57 }
58
59 protected void throwException(String message) throws SAXException {
60 throw new SAXException(
61 getCurrentPosition()
62 + message
63 );
64 }
65
66 protected long getMandatoryAttributeLong(Attributes attr, String name) throws SAXException{
67 String v = attr.getValue(name);
68 if (v == null) {
69 throwException(tr("Missing mandatory attribute ''{0}''.", name));
70 }
71 Long l = 0l;
72 try {
73 l = Long.parseLong(v);
74 } catch(NumberFormatException e) {
75 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
76 }
77 if (l < 0) {
78 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
79 }
80 return l;
81 }
82
83 protected long getAttributeLong(Attributes attr, String name, long defaultValue) throws SAXException{
84 String v = attr.getValue(name);
85 if (v == null)
86 return defaultValue;
87 Long l = 0l;
88 try {
89 l = Long.parseLong(v);
90 } catch(NumberFormatException e) {
91 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
92 }
93 if (l < 0) {
94 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
95 }
96 return l;
97 }
98
99 protected Double getMandatoryAttributeDouble(Attributes attr, String name) throws SAXException{
100 String v = attr.getValue(name);
101 if (v == null) {
102 throwException(tr("Missing mandatory attribute ''{0}''.", name));
103 }
104 double d = 0.0;
105 try {
106 d = Double.parseDouble(v);
107 } catch(NumberFormatException e) {
108 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type double. Got ''{1}''.", name, v));
109 }
110 return d;
111 }
112
113 protected String getMandatoryAttributeString(Attributes attr, String name) throws SAXException{
114 String v = attr.getValue(name);
115 if (v == null) {
116 throwException(tr("Missing mandatory attribute ''{0}''.", name));
117 }
118 return v;
119 }
120
121 protected String getAttributeString(Attributes attr, String name, String defaultValue) {
122 String v = attr.getValue(name);
123 if (v == null)
124 return defaultValue;
125 return v;
126 }
127
128 protected boolean getMandatoryAttributeBoolean(Attributes attr, String name) throws SAXException{
129 String v = attr.getValue(name);
130 if (v == null) {
131 throwException(tr("Missing mandatory attribute ''{0}''.", name));
132 }
133 if (v.equals("true")) return true;
134 if (v.equals("false")) return false;
135 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type boolean. Got ''{1}''.", name, v));
136 // not reached
137 return false;
138 }
139
140 protected HistoryOsmPrimitive createPrimitive(Attributes atts, OsmPrimitiveType type) throws SAXException {
141 long id = getMandatoryAttributeLong(atts,"id");
142 long version = getMandatoryAttributeLong(atts,"version");
143 long changesetId = getMandatoryAttributeLong(atts,"changeset");
144 boolean visible= getMandatoryAttributeBoolean(atts, "visible");
145 long uid = getAttributeLong(atts, "uid",-1);
146 String user = getAttributeString(atts, "user", tr("<anonymous>"));
147 String v = getMandatoryAttributeString(atts, "timestamp");
148 Date timestamp = DateUtils.fromString(v);
149 HistoryOsmPrimitive primitive = null;
150 if (type.equals(OsmPrimitiveType.NODE)) {
151 double lat = getMandatoryAttributeDouble(atts, "lat");
152 double lon = getMandatoryAttributeDouble(atts, "lon");
153 primitive = new HistoryNode(
154 id,version,visible,user,uid,changesetId,timestamp, new LatLon(lat,lon)
155 );
156
157 } else if (type.equals(OsmPrimitiveType.WAY)) {
158 primitive = new HistoryWay(
159 id,version,visible,user,uid,changesetId,timestamp
160 );
161 }if (type.equals(OsmPrimitiveType.RELATION)) {
162 primitive = new HistoryRelation(
163 id,version,visible,user,uid,changesetId,timestamp
164 );
165 }
166 return primitive;
167 }
168
169 protected void startNode(Attributes atts) throws SAXException {
170 current= createPrimitive(atts, OsmPrimitiveType.NODE);
171 }
172
173 protected void startWay(Attributes atts) throws SAXException {
174 current= createPrimitive(atts, OsmPrimitiveType.WAY);
175 }
176 protected void startRelation(Attributes atts) throws SAXException {
177 current= createPrimitive(atts, OsmPrimitiveType.RELATION);
178 }
179
180 protected void handleTag(Attributes atts) throws SAXException {
181 String key= getMandatoryAttributeString(atts, "k");
182 String value= getMandatoryAttributeString(atts, "v");
183 current.put(key,value);
184 }
185
186 protected void handleNodeReference(Attributes atts) throws SAXException {
187 long ref = getMandatoryAttributeLong(atts, "ref");
188 ((HistoryWay)current).addNode(ref);
189 }
190
191 protected void handleMember(Attributes atts) throws SAXException {
192 long ref = getMandatoryAttributeLong(atts, "ref");
193 String v = getMandatoryAttributeString(atts, "type");
194 OsmPrimitiveType type = null;
195 try {
196 type = OsmPrimitiveType.fromApiTypeName(v);
197 } catch(IllegalArgumentException e) {
198 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type OsmPrimitiveType. Got ''{1}''.", "type", v));
199 }
200 String role = getMandatoryAttributeString(atts, "role");
201 org.openstreetmap.josm.data.osm.history.RelationMember member = new org.openstreetmap.josm.data.osm.history.RelationMember(role, type,ref);
202 ((HistoryRelation)current).addMember(member);
203 }
204
205 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
206 if (qName.equals("node")) {
207 startNode(atts);
208 } else if (qName.equals("way")) {
209 startWay(atts);
210 } else if (qName.equals("relation")) {
211 startRelation(atts);
212 } else if (qName.equals("tag")) {
213 handleTag(atts);
214 } else if (qName.equals("nd")) {
215 handleNodeReference(atts);
216 } else if (qName.equals("member")) {
217 handleMember(atts);
218 }
219 }
220
221 @Override
222 public void endElement(String uri, String localName, String qName) throws SAXException {
223 if (qName.equals("node")
224 || qName.equals("way")
225 || qName.equals("relation")) {
226 data.put(current);
227 }
228 }
229 }
230
231 public OsmHistoryReader(InputStream source) {
232 this.in = source;
233 data = new HistoryDataSet();
234 }
235
236 public HistoryDataSet parse(ProgressMonitor progressMonitor) throws SAXException, IOException {
237 InputSource inputSource = new InputSource(new InputStreamReader(in, "UTF-8"));
238 progressMonitor.beginTask(tr("Parsing OSM history data ..."));
239 try {
240 SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new Parser());
241 } catch (ParserConfigurationException e1) {
242 e1.printStackTrace(); // broken SAXException chaining
243 throw new SAXException(e1);
244 } finally {
245 progressMonitor.finishTask();
246 }
247 return data;
248 }
249}
Note: See TracBrowser for help on using the repository browser.