Ticket #18249: 18249.3.patch
File 18249.3.patch, 9.7 KB (added by , 5 years ago) |
---|
-
src/org/openstreetmap/josm/io/OsmReader.java
6 6 import java.io.InputStream; 7 7 import java.util.Collection; 8 8 import java.util.Objects; 9 import java.util.Set; 10 import java.util.TreeSet; 9 11 import java.util.regex.Matcher; 10 12 import java.util.regex.Pattern; 11 13 … … 39 41 40 42 protected XMLStreamReader parser; 41 43 44 protected boolean convertUnknownToTags; 45 46 private static final Set<String> COMMON_XML_ATTRIBUTES = new TreeSet<>(); 47 48 static { 49 COMMON_XML_ATTRIBUTES.add("id"); 50 COMMON_XML_ATTRIBUTES.add("timestamp"); 51 COMMON_XML_ATTRIBUTES.add("user"); 52 COMMON_XML_ATTRIBUTES.add("uid"); 53 COMMON_XML_ATTRIBUTES.add("visible"); 54 COMMON_XML_ATTRIBUTES.add("version"); 55 COMMON_XML_ATTRIBUTES.add("action"); 56 COMMON_XML_ATTRIBUTES.add("changeset"); 57 COMMON_XML_ATTRIBUTES.add("lat"); 58 COMMON_XML_ATTRIBUTES.add("lon"); 59 } 60 42 61 /** 43 62 * constructor (for private and subclasses use only) 44 63 * … … 45 64 * @see #parseDataSet(InputStream, ProgressMonitor) 46 65 */ 47 66 protected OsmReader() { 67 this(false); 68 } 69 70 /** 71 * constructor (for private and subclasses use only) 72 * @param convertUnknownToTags if true, keep unknown xml attributes as tags 73 * 74 * @see #parseDataSet(InputStream, ProgressMonitor) 75 * @since xxx 76 */ 77 protected OsmReader(boolean convertUnknownToTags) { 48 78 // Restricts visibility 79 this.convertUnknownToTags = convertUnknownToTags; 49 80 } 50 81 51 82 protected void setParser(XMLStreamReader parser) { … … 393 424 parseVersion(current, parser.getAttributeValue(null, "version")); 394 425 parseAction(current, parser.getAttributeValue(null, "action")); 395 426 parseChangeset(current, parser.getAttributeValue(null, "changeset")); 427 428 if (convertUnknownToTags) { 429 for (int i = 0; i < parser.getAttributeCount(); i++) { 430 if (!COMMON_XML_ATTRIBUTES.contains(parser.getAttributeLocalName(i))) { 431 parseTag(current, parser.getAttributeLocalName(i), parser.getAttributeValue(i)); 432 } 433 } 434 } 396 435 } catch (UncheckedParseException | XMLStreamException e) { 397 436 throw new IllegalDataException(e); 398 437 } … … 457 496 * @throws IllegalArgumentException if source is null 458 497 */ 459 498 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException { 460 return new OsmReader().doParseDataSet(source, progressMonitor);499 return parseDataSet(source, progressMonitor, false); 461 500 } 501 502 /** 503 * Parse the given input source and return the dataset. 504 * 505 * @param source the source input stream. Must not be null. 506 * @param progressMonitor the progress monitor. If null, {@link NullProgressMonitor#INSTANCE} is assumed 507 * @param convertUnknownToTags true if unknown xml attributes should be kept as tags 508 * 509 * @return the dataset with the parsed data 510 * @throws IllegalDataException if an error was found while parsing the data from the source 511 * @throws IllegalArgumentException if source is null 512 * @since xxx 513 */ 514 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor, boolean convertUnknownToTags) 515 throws IllegalDataException { 516 return new OsmReader(convertUnknownToTags).doParseDataSet(source, progressMonitor); 517 } 462 518 } -
test/unit/org/openstreetmap/josm/io/OsmReaderTest.java
12 12 import java.nio.charset.StandardCharsets; 13 13 import java.nio.file.Files; 14 14 import java.nio.file.Paths; 15 import java.util.Arrays; 15 16 16 17 import org.junit.Rule; 17 18 import org.junit.Test; 18 19 import org.openstreetmap.josm.TestUtils; 19 20 import org.openstreetmap.josm.data.osm.DataSet; 21 import org.openstreetmap.josm.data.osm.Node; 20 22 import org.openstreetmap.josm.data.osm.Way; 21 23 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 22 24 import org.openstreetmap.josm.gui.progress.ProgressMonitor; … … 73 75 ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) { 74 76 assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE).allPrimitives().isEmpty()); 75 77 } 78 testUnknown(osm, true); 79 testUnknown(osm, false); 76 80 } 77 81 82 private static void testUnknown(String osm, boolean parseUnknownAttributes) throws Exception { 83 try (InputStream in = new ByteArrayInputStream( 84 ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) { 85 assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes).allPrimitives() 86 .isEmpty()); 87 } 88 } 89 78 90 /** 79 91 * Unit test of {@link OsmReader#parseUnknown} - root case. 80 92 * @throws Exception if any error occurs … … 126 138 } 127 139 128 140 /** 141 * Test valid data. 142 * @param osm OSM data without XML prefix 143 * @param parseUnknownAttributes if true, attempt to parse unknown xml attributes 144 * @return parsed data set 145 * @throws Exception if any error occurs 146 */ 147 private static DataSet testValidData(String osm, boolean parseUnknownAttributes) throws Exception { 148 try (InputStream in = new ByteArrayInputStream( 149 ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) { 150 return OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes); 151 } 152 } 153 154 /** 129 155 * Test invalid data. 130 156 * @param osm OSM data without XML prefix 131 157 * @param expectedError expected error message … … 139 165 } catch (IllegalDataException e) { 140 166 assertEquals(expectedError, e.getMessage()); 141 167 } 168 testInvalidData(osm, expectedError, true); 169 testInvalidData(osm, expectedError, false); 142 170 } 143 171 144 172 /** 173 * Test invalid data. 174 * 175 * @param osm OSM data without XML prefix 176 * @param expectedError expected error message 177 * @param parseUnknownAttributes if true, attempt to parse unknown xml 178 * attributes 179 * @throws Exception if any error occurs 180 */ 181 private static void testInvalidData(String osm, String expectedError, boolean parseUnknownAttributes) 182 throws Exception { 183 try (InputStream in = new ByteArrayInputStream( 184 ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) { 185 OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes); 186 fail("should throw exception"); 187 } catch (IllegalDataException e) { 188 assertEquals(expectedError, e.getMessage()); 189 } 190 } 191 192 /** 145 193 * Test invalid UID. 146 194 * @throws Exception if any error occurs 147 195 */ … … 274 322 */ 275 323 @Test 276 324 public void testGdprChangeset() throws Exception { 277 testValidData("<osm version='0.6'><node id='1' version='1' changeset='0'/></osm>"); 325 String gdprChangeset = "<osm version='0.6'><node id='1' version='1' changeset='0'/></osm>"; 326 testValidData(gdprChangeset); 327 testValidData(gdprChangeset, true); 328 testValidData(gdprChangeset, false); 278 329 } 279 330 280 331 /** … … 349 400 */ 350 401 @Test 351 402 public void testRemark() throws Exception { 352 DataSet ds = testValidData( 353 "<osm version=\"0.6\" generator=\"Overpass API 0.7.55.4 3079d8ea\">\r\n" + 403 String query = "<osm version=\"0.6\" generator=\"Overpass API 0.7.55.4 3079d8ea\">\r\n" + 354 404 "<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>\r\n" + 355 405 "<meta osm_base=\"2018-08-30T12:46:02Z\" areas=\"2018-08-30T12:40:02Z\"/>\r\n" + 356 406 "<remark>runtime error: Query ran out of memory in \"query\" at line 5.</remark>\r\n" + 357 "</osm>"); 358 assertEquals("runtime error: Query ran out of memory in \"query\" at line 5.", ds.getRemark()); 407 "</osm>"; 408 for (DataSet ds : Arrays.asList(testValidData(query), testValidData(query, true), testValidData(query, false))) { 409 assertEquals("runtime error: Query ran out of memory in \"query\" at line 5.", ds.getRemark()); 410 } 359 411 } 412 413 /** 414 * Test reading a file with unknown attributes in osm primitives 415 * @throws Exception if any error occurs 416 */ 417 @Test 418 public void testUnknownAttributeTags() throws Exception { 419 String testData = "<osm version=\"0.6\" generator=\"fake generator\">" 420 + "<node id='1' version='1' visible='true' changeset='82' randomkey='randomvalue'></node>" + "</osm>"; 421 DataSet ds = testValidData(testData); 422 assertEquals(0, ds.getNodes().iterator().next().getKeys().size()); 423 424 ds = testValidData(testData, true); 425 Node firstNode = ds.getNodes().iterator().next(); 426 assertEquals(1, firstNode.getKeys().size()); 427 assertEquals("randomvalue", firstNode.get("randomkey")); 428 429 ds = testValidData(testData, false); 430 assertEquals(0, ds.getNodes().iterator().next().getKeys().size()); 431 } 360 432 }