Ticket #18258: 18258.5.patch

File 18258.5.patch, 12.9 KB (added by taylor.smock, 6 years ago)

Add javadoc, enum is public, remove methods that would otherwise be deprecated (only affects the MapWithAI plugin, as far as we know)

  • src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

     
    734734                    Arrays.asList(
    735735                            "created_by",
    736736                            "converted_by",
     737                            "current_id",
    737738                            "geobase:datasetName",
    738739                            "geobase:uuid",
    739740                            "KSJ2:ADS",
  • src/org/openstreetmap/josm/io/OsmReader.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.io.InputStream;
     7import java.util.Arrays;
    78import java.util.Collection;
     9import java.util.Collections;
    810import java.util.Objects;
    911import java.util.Set;
    1012import java.util.TreeSet;
     
    3941 */
    4042public class OsmReader extends AbstractReader {
    4143
     44    /**
     45     * Options are used to change how the xml data is parsed.
     46     * For example, {@link Options#CONVERT_UNKNOWN_TO_TAGS} is used to convert unknown
     47     * XML attributes to a tag for the object.
     48     */
     49    public enum Options {
     50        /** Convert unknown XML attributes to tags */
     51        CONVERT_UNKNOWN_TO_TAGS,
     52        /** Save the original id of an object (currently stored in `current_id`) */
     53        SAVE_ORIGINAL_ID
     54    }
     55
    4256    protected XMLStreamReader parser;
    4357
    44     protected boolean convertUnknownToTags;
     58    /** The {@link OsmReader.Options} to use when parsing the xml data */
     59    protected Collection<Options> options;
    4560
    4661    private static final Set<String> COMMON_XML_ATTRIBUTES = new TreeSet<>();
    4762
     
    6479     * @see #parseDataSet(InputStream, ProgressMonitor)
    6580     */
    6681    protected OsmReader() {
    67         this(false);
     82        this((Options) null);
    6883    }
    6984
    7085    /**
    7186     * constructor (for private and subclasses use only)
    72      * @param convertUnknownToTags if true, keep unknown xml attributes as tags
     87     * @param options The options to use when reading data
    7388     *
    7489     * @see #parseDataSet(InputStream, ProgressMonitor)
    75      * @since 15470
     90     * @since xxx
    7691     */
    77     protected OsmReader(boolean convertUnknownToTags) {
     92    protected OsmReader(Options... options) {
    7893        // Restricts visibility
    79         this.convertUnknownToTags = convertUnknownToTags;
     94        this.options = options == null ? Collections.emptyList() : Arrays.asList(options);
    8095    }
    8196
    8297    protected void setParser(XMLStreamReader parser) {
     
    425440            parseAction(current, parser.getAttributeValue(null, "action"));
    426441            parseChangeset(current, parser.getAttributeValue(null, "changeset"));
    427442
    428             if (convertUnknownToTags) {
     443            if (options.contains(Options.SAVE_ORIGINAL_ID)) {
     444                parseTag(current, "current_id", Long.toString(getLong("id")));
     445            }
     446            if (options.contains(Options.CONVERT_UNKNOWN_TO_TAGS)) {
    429447                for (int i = 0; i < parser.getAttributeCount(); i++) {
    430448                    if (!COMMON_XML_ATTRIBUTES.contains(parser.getAttributeLocalName(i))) {
    431449                        parseTag(current, parser.getAttributeLocalName(i), parser.getAttributeValue(i));
     
    496514     * @throws IllegalArgumentException if source is null
    497515     */
    498516    public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
    499         return parseDataSet(source, progressMonitor, false);
     517        return parseDataSet(source, progressMonitor, (Options) null);
    500518    }
    501519
    502520    /**
     
    504522     *
    505523     * @param source the source input stream. Must not be null.
    506524     * @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
     525     * @param options The options to use when parsing the dataset
    508526     *
    509527     * @return the dataset with the parsed data
    510528     * @throws IllegalDataException if an error was found while parsing the data from the source
    511529     * @throws IllegalArgumentException if source is null
    512      * @since 15470
     530     * @since xxx
    513531     */
    514     public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor, boolean convertUnknownToTags)
     532    public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor, Options... options)
    515533            throws IllegalDataException {
    516         return new OsmReader(convertUnknownToTags).doParseDataSet(source, progressMonitor);
     534        return new OsmReader(options).doParseDataSet(source, progressMonitor);
    517535    }
    518536}
  • test/unit/org/openstreetmap/josm/io/OsmReaderTest.java

     
    66import static org.junit.Assert.assertNull;
    77import static org.junit.Assert.assertTrue;
    88import static org.junit.Assert.fail;
     9import static org.junit.jupiter.api.Assertions.assertNotEquals;
    910
    1011import java.io.ByteArrayInputStream;
    1112import java.io.InputStream;
     
    2223import org.openstreetmap.josm.data.osm.Way;
    2324import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2425import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     26import org.openstreetmap.josm.io.OsmReader.Options;
    2527import org.openstreetmap.josm.testutils.JOSMTestRules;
    2628
    2729import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     
    8284    private static void testUnknown(String osm, boolean parseUnknownAttributes) throws Exception {
    8385        try (InputStream in = new ByteArrayInputStream(
    8486                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
    85             assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes).allPrimitives()
     87            assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS).allPrimitives()
    8688                    .isEmpty());
    8789        }
     90        testUnknown(osm, parseUnknownAttributes, true);
     91        testUnknown(osm, parseUnknownAttributes, true);
    8892    }
    8993
     94    private static void testUnknown(String osm, boolean parseUnknownAttributes, boolean keepOriginalId)
     95            throws Exception {
     96        try (InputStream in = new ByteArrayInputStream(
     97                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
     98            assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS, Options.SAVE_ORIGINAL_ID)
     99                    .allPrimitives().isEmpty());
     100        }
     101    }
     102
    90103    /**
    91104     * Unit test of {@link OsmReader#parseUnknown} - root case.
    92105     * @throws Exception if any error occurs
     
    147160    private static DataSet testValidData(String osm, boolean parseUnknownAttributes) throws Exception {
    148161        try (InputStream in = new ByteArrayInputStream(
    149162                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
    150             return OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes);
     163            return OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS);
    151164        }
    152165    }
    153166
    154167    /**
     168     * Test valid data.
     169     *
     170     * @param osm                    OSM data without XML prefix
     171     * @param parseUnknownAttributes if true, attempt to parse unknown xml
     172     *                               attributes
     173     * @param keepOriginalId         if true, keep the original id of the object (if
     174     *                               a negative id)
     175     * @return parsed data set
     176     * @throws Exception if any error occurs
     177     */
     178    private static DataSet testValidData(String osm, boolean parseUnknownAttributes, boolean keepOriginalId)
     179            throws Exception {
     180        try (InputStream in = new ByteArrayInputStream(
     181                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
     182            return OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS, Options.SAVE_ORIGINAL_ID);
     183        }
     184    }
     185
     186    /**
    155187     * Test invalid data.
    156188     * @param osm OSM data without XML prefix
    157189     * @param expectedError expected error message
     
    182214            throws Exception {
    183215        try (InputStream in = new ByteArrayInputStream(
    184216                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
    185             OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes);
     217            OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS);
    186218            fail("should throw exception");
    187219        } catch (IllegalDataException e) {
    188220            assertEquals(expectedError, e.getMessage());
     
    326358        testValidData(gdprChangeset);
    327359        testValidData(gdprChangeset, true);
    328360        testValidData(gdprChangeset, false);
     361        testValidData(gdprChangeset, false, true);
     362        testValidData(gdprChangeset, true, false);
     363        testValidData(gdprChangeset, false, false);
     364        testValidData(gdprChangeset, true, true);
    329365    }
    330366
    331367    /**
     
    405441                "<meta osm_base=\"2018-08-30T12:46:02Z\" areas=\"2018-08-30T12:40:02Z\"/>\r\n" +
    406442                "<remark>runtime error: Query ran out of memory in \"query\" at line 5.</remark>\r\n" +
    407443                "</osm>";
    408         for (DataSet ds : Arrays.asList(testValidData(query), testValidData(query, true), testValidData(query, false))) {
     444        for (DataSet ds : Arrays.asList(testValidData(query), testValidData(query, true), testValidData(query, false),
     445                testValidData(query, true, false), testValidData(query, false, false), testValidData(query, true, true),
     446                testValidData(query, false, true))) {
    409447            assertEquals("runtime error: Query ran out of memory in \"query\" at line 5.", ds.getRemark());
    410448        }
    411449    }
     
    420458                + "<node id='1' version='1' visible='true' changeset='82' randomkey='randomvalue'></node>" + "</osm>";
    421459        DataSet ds = testValidData(testData);
    422460        assertEquals(0, ds.getNodes().iterator().next().getKeys().size());
     461        assertEquals(1, ds.getNodes().iterator().next().getUniqueId());
    423462
    424         ds = testValidData(testData, true);
    425         Node firstNode = ds.getNodes().iterator().next();
    426         assertEquals(1, firstNode.getKeys().size());
    427         assertEquals("randomvalue", firstNode.get("randomkey"));
     463        for (DataSet ds1 : Arrays.asList(testValidData(testData, true), testValidData(testData, true, false),
     464                testValidData(testData, true, true))) {
     465            ds = ds1;
     466            Node firstNode = ds.getNodes().iterator().next();
     467            assertEquals(1, firstNode.getKeys().size());
     468            assertEquals("randomvalue", firstNode.get("randomkey"));
     469            assertEquals(1, ds.getNodes().iterator().next().getUniqueId());
     470        }
    428471
    429         ds = testValidData(testData, false);
    430         assertEquals(0, ds.getNodes().iterator().next().getKeys().size());
     472        for (DataSet ds1 : Arrays.asList(testValidData(testData, false), testValidData(testData, false, false),
     473                testValidData(testData, false, true))) {
     474            ds = ds1;
     475            assertEquals(0, ds.getNodes().iterator().next().getKeys().size());
     476            assertEquals(1, ds.getNodes().iterator().next().getUniqueId());
     477        }
    431478    }
     479
     480    /**
     481     * Test reading a file with negative ids in osm primitives
     482     *
     483     * @throws Exception if any error occurs
     484     */
     485    @Test
     486    public void testNegativeIds() throws Exception {
     487        String testData = "<osm version=\"0.6\" generator=\"fake generator\">"
     488                + "<node id='-1' version='1' visible='true' changeset='82' randomkey='randomvalue'></node>" + "</osm>";
     489        DataSet ds = testValidData(testData);
     490        assertNotEquals(-1L, ds.getNodes().iterator().next().getUniqueId());
     491
     492        for (DataSet ds1 : Arrays.asList(testValidData(testData, true), testValidData(testData, true, false),
     493                testValidData(testData, true, false))) {
     494            ds = ds1;
     495            assertNotEquals(-1L, ds.getNodes().iterator().next().getUniqueId());
     496        }
     497
     498        for (DataSet ds1 : Arrays.asList(testValidData(testData, true, true), testValidData(testData, false, true))) {
     499            ds = ds1;
     500            assertEquals(-1L, ds.getNodes().iterator().next().getUniqueId()); // if we set the id to the original id
     501            assertEquals("-1", ds.getNodes().iterator().next().get("current_id")); // if we just add a tag
     502        }
     503    }
    432504}