Changeset 6562 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2013-12-29T14:14:58+01:00 (11 years ago)
Author:
simon04
Message:

fix #9327 - tagging presets: fix handling of nested <reference>s, refactor railway presets

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetReader.java

    r6558 r6562  
    1717import java.util.List;
    1818import java.util.Map;
     19import java.util.Stack;
    1920
    2021import javax.swing.JOptionPane;
     
    9293        List<TaggingPresetItems.PresetListEntry> listEntries = new LinkedList<TaggingPresetItems.PresetListEntry>();
    9394        final Map<String, List<Object>> byId = new HashMap<String, List<Object>>();
    94         String lastId = null;
    95         Iterator<Object> lastIdIterator = null;
     95        final Stack<String> lastIds = new Stack<String>();
     96        /** lastIdIterators contains non empty iterators of items to be handled before obtaining the next item from the XML parser */
     97        final Stack<Iterator<Object>> lastIdIterators = new Stack<Iterator<Object>>();
    9698
    9799        if (validate) {
     
    100102            parser.start(in);
    101103        }
    102         while (parser.hasNext()) {
     104        while (parser.hasNext() || !lastIdIterators.isEmpty()) {
    103105            final Object o;
    104             if (lastIdIterator != null && lastIdIterator.hasNext()) {
    105                 // obtain elements from lastIdIterator with higher priority
    106                 o = lastIdIterator.next();
     106            if (!lastIdIterators.isEmpty()) {
     107                // obtain elements from lastIdIterators with higher priority
     108                o = lastIdIterators.peek().next();
     109                if (!lastIdIterators.peek().hasNext()) {
     110                    // remove iterator is is empty
     111                    lastIdIterators.pop();
     112                }
    107113            } else {
    108114                o = parser.next();
    109115            }
    110116            if (o instanceof Chunk) {
    111                 if (((Chunk) o).id.equals(lastId)) {
    112                     // reset last id on end of object, don't process further
    113                     lastId = null;
     117                if (!lastIds.isEmpty() && ((Chunk) o).id.equals(lastIds.peek())) {
     118                    // pop last id on end of object, don't process further
     119                    lastIds.pop();
    114120                    ((Chunk) o).id = null;
    115121                    continue;
    116                 } else if (lastId == null) {
     122                } else {
    117123                    // if preset item contains an id, store a mapping for later usage
    118                     lastId = ((Chunk) o).id;
     124                    String lastId = ((Chunk) o).id;
     125                    lastIds.push(lastId);
    119126                    byId.put(lastId, new ArrayList<Object>());
    120127                    continue;
    121                 } else {
    122                     throw new IllegalStateException("Cannot deal with nested id objects (lastId was expected to be null)");
    123                 }
    124             } else if (lastId != null) {
     128                }
     129            } else if (!lastIds.isEmpty()) {
    125130                // add object to mapping for later usage
    126                 byId.get(lastId).add(o);
     131                byId.get(lastIds.peek()).add(o);
    127132                continue;
    128133            }
     
    134139                    throw new SAXException(tr("Reference {0} is being used before it was defined", ref));
    135140                }
    136                 lastIdIterator = byId.get(ref).iterator();
     141                lastIdIterators.push(byId.get(ref).iterator());
    137142                continue;
    138143            }
Note: See TracChangeset for help on using the changeset viewer.