Changeset 9887 in josm


Ignore:
Timestamp:
2016-02-27T15:52:04+01:00 (4 years ago)
Author:
wiktorn
Message:

Properly interpret more complex getCapabilities documents.

Keep a track of how deep into the XML tree reader has traversed. Do the
interpretation of the tags only if they are present at proper level.

If unknown tag is found, move the reader to the end of the tag, to avoid
confusion.

When using moveToReader within parseLayer, it is needed, to keep tagStack
updated.

This should fix problems with BE WMTS imagery - See: #12573

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java

    r9830 r9887  
    2020import java.util.Set;
    2121import java.util.SortedSet;
     22import java.util.Stack;
    2223import java.util.TreeSet;
    2324import java.util.concurrent.ConcurrentHashMap;
     
    368369    private static Layer parseLayer(XMLStreamReader reader) throws XMLStreamException {
    369370        Layer layer = new Layer();
     371        Stack<QName> tagStack = new Stack<>();
    370372
    371373        for (int event = reader.getEventType();
     
    373375                event = reader.next()) {
    374376            if (event == XMLStreamReader.START_ELEMENT) {
    375                 if (new QName(WMTS_NS_URL, "Format").equals(reader.getName())) {
    376                     layer.format = reader.getElementText();
    377                 }
    378                 if (new QName(OWS_NS_URL, "Identifier").equals(reader.getName())) {
    379                     layer.name = reader.getElementText();
    380                 }
    381                 if (new QName(WMTS_NS_URL, "ResourceURL").equals(reader.getName()) &&
    382                         "tile".equals(reader.getAttributeValue("", "resourceType"))) {
    383                     layer.baseUrl = reader.getAttributeValue("", "template");
    384                 }
    385                 if (new QName(WMTS_NS_URL, "Style").equals(reader.getName()) &&
    386                         "true".equals(reader.getAttributeValue("", "isDefault")) &&
    387                         moveReaderToTag(reader, new QName[] {new QName(OWS_NS_URL, "Identifier")})) {
    388                     layer.style = reader.getElementText();
    389                 }
    390                 if (new QName(WMTS_NS_URL, "TileMatrixSetLink").equals(reader.getName())) {
    391                     layer.tileMatrixSetLinks.add(praseTileMatrixSetLink(reader));
     377                tagStack.push(reader.getName());
     378                if (tagStack.size() == 2) {
     379                    if (new QName(WMTS_NS_URL, "Format").equals(reader.getName())) {
     380                        layer.format = reader.getElementText();
     381                    } else if (new QName(OWS_NS_URL, "Identifier").equals(reader.getName())) {
     382                        layer.name = reader.getElementText();
     383                    } else if (new QName(WMTS_NS_URL, "ResourceURL").equals(reader.getName()) &&
     384                            "tile".equals(reader.getAttributeValue("", "resourceType"))) {
     385                        layer.baseUrl = reader.getAttributeValue("", "template");
     386                    } else if (new QName(WMTS_NS_URL, "Style").equals(reader.getName()) &&
     387                            "true".equals(reader.getAttributeValue("", "isDefault")) &&
     388                            moveReaderToTag(reader, new QName[] {new QName(OWS_NS_URL, "Identifier")})) {
     389                        layer.style = reader.getElementText();
     390                        tagStack.push(reader.getName()); // keep tagStack in sync
     391                    } else if (new QName(WMTS_NS_URL, "TileMatrixSetLink").equals(reader.getName())) {
     392                        layer.tileMatrixSetLinks.add(praseTileMatrixSetLink(reader));
     393                    } else {
     394                        moveReaderToEndCurrentTag(reader);
     395                    }
     396                }
     397            }
     398            // need to get event type from reader, as parsing might have change position of reader
     399            if (reader.getEventType() == XMLStreamReader.END_ELEMENT) {
     400                QName start = tagStack.pop();
     401                if (!start.equals(reader.getName())) {
     402                    throw new IllegalStateException(tr("WMTS Parser error - start element {0} has different name than end element {2}",
     403                            start, reader.getName()));
    392404                }
    393405            }
     
    397409        }
    398410        return layer;
     411    }
     412
     413    /**
     414     * Moves the reader to the closing tag of current tag.
     415     * @param reader XML stream reader positioned on XMLStreamReader.START_ELEMENT
     416     * @throws XMLStreamException when parse exception occurs
     417     */
     418    private static void moveReaderToEndCurrentTag(XMLStreamReader reader) throws XMLStreamException {
     419        int level = 0;
     420        QName tag = reader.getName();
     421        for (int event = reader.getEventType(); reader.hasNext(); event = reader.next()) {
     422            switch (event) {
     423            case XMLStreamReader.START_ELEMENT:
     424                level += 1;
     425                break;
     426            case XMLStreamReader.END_ELEMENT:
     427                level -= 1;
     428                if (level == 0 && tag.equals(reader.getName())) {
     429                    return;
     430                }
     431            }
     432            if (level < 0) {
     433                throw new IllegalStateException("WMTS Parser error - moveReaderToEndCurrentTag failed to find closing tag");
     434            }
     435        }
     436        throw new IllegalStateException("WMTS Parser error - moveReaderToEndCurrentTag failed to find closing tag");
     437
    399438    }
    400439
Note: See TracChangeset for help on using the changeset viewer.