Changeset 6562 in josm


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

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

Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/data/defaultpresets.xml

    r6559 r6562  
    183183        <text key="width" text="Width (meters)" />
    184184    </chunk>
     185    <chunk id="railway_service">
     186        <combo key="service" text="Service type" values="yard,siding,spur" />
     187    </chunk>
     188    <chunk id="railway_electrified">
     189        <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
     190        <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
     191        <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     192    </chunk>
     193    <chunk id="railway_service_gauge_electrified">
     194        <reference ref="railway_service" />
     195        <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
     196        <reference ref="railway_electrified" />
     197    </chunk>
    185198    <chunk id="barrier_5">
    186199        <optional text="Allowed traffic:">
     
    19091922            <optional>
    19101923                <combo key="usage" text="Usage" values="main,branch,industrial,military,tourism,freight" />
    1911                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1912                 <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
    1913                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1914                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1915                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1924                <reference ref="railway_service_gauge_electrified" />
    19161925            </optional>
    19171926        </item>
     
    19221931            <optional>
    19231932                <combo key="usage" text="Usage" values="main,branch,industrial,military,tourism,freight" />
    1924                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1925                 <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
    1926                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1927                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1928                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1933                <reference ref="railway_service_gauge_electrified" />
    19291934            </optional>
    19301935        </item>
     
    19371942            <key key="railway" value="monorail" />
    19381943            <optional>
    1939                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1940                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1941                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1942                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1944                <reference ref="railway_service" />
     1945                <reference ref="railway_electrified" />
    19431946            </optional>
    19441947        </item>
     
    19481951            <key key="railway" value="preserved" />
    19491952            <optional>
    1950                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1951                 <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
    1952                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1953                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1954                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1953                <reference ref="railway_service_gauge_electrified" />
    19551954            </optional>
    19561955        </item>
     
    19601959            <key key="railway" value="light_rail" />
    19611960            <optional>
    1962                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1963                 <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
    1964                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1965                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1966                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1961                <reference ref="railway_service_gauge_electrified" />
    19671962            </optional>
    19681963        </item>
     
    19751970            <key key="railway" value="subway" />
    19761971            <optional>
    1977                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1978                 <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
    1979                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1980                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1981                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1972                <reference ref="railway_service_gauge_electrified" />
    19821973            </optional>
    19831974        </item>
     
    19921983            <key key="railway" value="tram" />
    19931984            <optional>
    1994                 <combo key="service" text="Service type" values="yard,siding,spur" />
    1995                 <combo key="gauge" text="Gauge (mm)" values="1668,1676,1674,1600,1524,1520,1495,1435,1067,1000,914,762,760,750" length="4" />
    1996                 <combo key="electrified" text="Electrified" values="contact_line,no,yes,rail" />
    1997                 <combo key="voltage" text="Voltage in Volts (V)" values="600,650,750,1500,3000,15000,25000" length="5" />
    1998                 <combo key="frequency" text="Frequency in Hertz (Hz)" values="0,16.67,16.7" length="5" />
     1985                <reference ref="railway_service_gauge_electrified" />
    19991986            </optional>
    20001987        </item>
     
    20212008            <key key="railway" value="disused" />
    20222009            <optional>
    2023                 <combo key="service" text="Service type" values="yard,siding,spur" />
     2010                <reference ref="railway_service" />
    20242011            </optional>
    20252012        </item>
     
    20302017            <key key="railway" value="abandoned" />
    20312018            <optional>
    2032                 <combo key="service" text="Service type" values="yard,siding,spur" />
     2019                <reference ref="railway_service" />
    20332020            </optional>
    20342021        </item>
  • 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            }
  • trunk/test/unit/org/openstreetmap/josm/gui/tagging/TaggingPresetReaderTest.java

    r6471 r6562  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging;
    3 
    4 import java.io.IOException;
    5 import java.util.Collection;
    63
    74import org.junit.Assert;
    85import org.junit.BeforeClass;
    96import org.junit.Test;
     7import org.openstreetmap.TestUtils;
    108import org.openstreetmap.josm.Main;
    11 import org.openstreetmap.josm.data.Preferences;
     9import org.openstreetmap.josm.tools.Utils;
    1210import org.xml.sax.SAXException;
     11
     12import java.io.IOException;
     13import java.util.Collection;
     14import java.util.List;
     15
     16import static org.CustomMatchers.hasSize;
     17import static org.hamcrest.CoreMatchers.is;
     18import static org.junit.Assert.assertThat;
    1319
    1420/**
     
    1622 */
    1723public class TaggingPresetReaderTest {
    18     /**
    19      * path to test data root directory
    20      */
    21     private static String testdataroot;
    22    
     24
    2325    @BeforeClass
    2426    public static void setUpClass() {
    2527        Main.initApplicationPreferences();
    26         testdataroot = System.getProperty("josm.test.data");
    27         if (testdataroot == null || testdataroot.isEmpty()) {
    28             testdataroot = "test/data";
    29             System.out.println("System property josm.test.data is not set, using '" + testdataroot + "'");
    30         }
    3128    }
    3229
     
    3734     */
    3835    protected static String getRegressionDataDir(int ticketid) {
    39         return testdataroot + "/regress/" + ticketid;
     36        return TestUtils.getTestDataRoot() + "/regress/" + ticketid;
    4037    }
    4138
     
    6461    }
    6562
     63    @Test
     64    public void testNestedChunks() throws Exception {
     65        final Collection<TaggingPreset> presets = TaggingPresetReader.readAll(TestUtils.getTestDataRoot() + "preset_chunk.xml", true);
     66        assertThat(presets, hasSize(1));
     67        final TaggingPreset abc =  presets.iterator().next();
     68        final List<String> keys = Utils.transform(abc.data, new Utils.Function<TaggingPresetItem, String>() {
     69            @Override
     70            public String apply(TaggingPresetItem x) {
     71                return ((TaggingPresetItems.Key) x).key;
     72            }
     73        });
     74        assertThat(keys.toString(), is("[A1, A2, A3, B1, B2, B3, C1, C2, C3]"));
     75    }
     76
    6677    /**
    6778     * Validate internal presets
Note: See TracChangeset for help on using the changeset viewer.