Ignore:
Timestamp:
2013-08-27T03:03:11+02:00 (11 years ago)
Author:
Don-vip
Message:

history/changeset parsing: refactor lots of duplicated code + update javadoc

Location:
trunk/src/org/openstreetmap/josm/io
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java

    r6090 r6201  
    99import java.io.StringReader;
    1010import java.io.UnsupportedEncodingException;
    11 import java.util.Date;
    1211
    1312import javax.xml.parsers.ParserConfigurationException;
    1413import javax.xml.parsers.SAXParserFactory;
    1514
    16 import org.openstreetmap.josm.data.coor.LatLon;
    1715import org.openstreetmap.josm.data.osm.ChangesetDataSet;
    18 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    19 import org.openstreetmap.josm.data.osm.RelationMemberData;
    20 import org.openstreetmap.josm.data.osm.User;
    2116import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType;
    22 import org.openstreetmap.josm.data.osm.history.HistoryNode;
    23 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
    24 import org.openstreetmap.josm.data.osm.history.HistoryRelation;
    25 import org.openstreetmap.josm.data.osm.history.HistoryWay;
    2617import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2718import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2819import org.openstreetmap.josm.tools.CheckParameterUtil;
    29 import org.openstreetmap.josm.tools.DateUtils;
    3020import org.xml.sax.Attributes;
    3121import org.xml.sax.InputSource;
    32 import org.xml.sax.Locator;
    3322import org.xml.sax.SAXException;
    3423import org.xml.sax.SAXParseException;
    35 import org.xml.sax.helpers.DefaultHandler;
    3624
    3725/**
    3826 * Parser for OSM changeset content.
    39  *
     27 * @since 2688
    4028 */
    4129public class OsmChangesetContentParser {
    4230
    4331    private InputSource source;
    44     private ChangesetDataSet data;
     32    private final ChangesetDataSet data = new ChangesetDataSet();
    4533
    46     // FIXME: this class has many similarities with OsmHistoryReader.Parser and should be merged
    47     private class Parser extends DefaultHandler {
     34    private class Parser extends AbstractParser {
    4835
    49         /** the current primitive to be read */
    50         private HistoryOsmPrimitive currentPrimitive;
    5136        /** the current change modification type */
    5237        private ChangesetDataSet.ChangesetModificationType currentModificationType;
    5338
    54         private Locator locator;
    55 
    56         @Override
    57         public void setDocumentLocator(Locator locator) {
    58             this.locator = locator;
    59         }
    60 
    6139        protected void throwException(String message) throws OsmDataParsingException {
    62             throw new OsmDataParsingException(
    63                     message
    64             ).rememberLocation(locator);
     40            throw new OsmDataParsingException(message).rememberLocation(locator);
    6541        }
    6642
    6743        protected void throwException(Exception e) throws OsmDataParsingException {
    68             throw new OsmDataParsingException(
    69                     e
    70             ).rememberLocation(locator);
    71         }
    72 
    73         protected long getMandatoryAttributeLong(Attributes attr, String name) throws SAXException{
    74             String v = attr.getValue(name);
    75             if (v == null) {
    76                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    77             }
    78             Long l = 0L;
    79             try {
    80                 l = Long.parseLong(v);
    81             } catch(NumberFormatException e) {
    82                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
    83             }
    84             if (l < 0) {
    85                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
    86             }
    87             return l;
    88         }
    89 
    90         protected Long getAttributeLong(Attributes attr, String name) throws SAXException{
    91             String v = attr.getValue(name);
    92             if (v == null)
    93                 return null;
    94             Long l = null;
    95             try {
    96                 l = Long.parseLong(v);
    97             } catch(NumberFormatException e) {
    98                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
    99             }
    100             if (l < 0) {
    101                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
    102             }
    103             return l;
    104         }
    105 
    106         protected Double getAttributeDouble(Attributes attr, String name) throws SAXException{
    107             String v = attr.getValue(name);
    108             if (v == null) {
    109                 return null;
    110             }
    111             double d = 0.0;
    112             try {
    113                 d = Double.parseDouble(v);
    114             } catch(NumberFormatException e) {
    115                 throwException(tr("Illegal value for attribute ''{0}'' of type double. Got ''{1}''.", name, v));
    116             }
    117             return d;
    118         }
    119 
    120         protected String getMandatoryAttributeString(Attributes attr, String name) throws SAXException{
    121             String v = attr.getValue(name);
    122             if (v == null) {
    123                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    124             }
    125             return v;
    126         }
    127 
    128         protected boolean getMandatoryAttributeBoolean(Attributes attr, String name) throws SAXException{
    129             String v = attr.getValue(name);
    130             if (v == null) {
    131                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    132             }
    133             if ("true".equals(v)) return true;
    134             if ("false".equals(v)) return false;
    135             throwException(tr("Illegal value for mandatory attribute ''{0}'' of type boolean. Got ''{1}''.", name, v));
    136             // not reached
    137             return false;
    138         }
    139 
    140         protected  HistoryOsmPrimitive createPrimitive(Attributes atts, OsmPrimitiveType type) throws SAXException {
    141             long id = getMandatoryAttributeLong(atts,"id");
    142             long version = getMandatoryAttributeLong(atts,"version");
    143             long changesetId = getMandatoryAttributeLong(atts,"changeset");
    144             boolean visible= getMandatoryAttributeBoolean(atts, "visible");
    145 
    146             Long uid = getAttributeLong(atts, "uid");
    147             String userStr = atts.getValue("user");
    148             User user;
    149             if (userStr != null) {
    150                 if (uid != null) {
    151                     user = User.createOsmUser(uid, userStr);
    152                 } else {
    153                     user = User.createLocalUser(userStr);
    154                 }
    155             } else {
    156                 user = User.getAnonymous();
    157             }
    158 
    159             String v = getMandatoryAttributeString(atts, "timestamp");
    160             Date timestamp = DateUtils.fromString(v);
    161             HistoryOsmPrimitive primitive = null;
    162             if (type.equals(OsmPrimitiveType.NODE)) {
    163                 Double lat = getAttributeDouble(atts, "lat");
    164                 Double lon = getAttributeDouble(atts, "lon");
    165                 LatLon coor = (lat != null && lon != null) ? new LatLon(lat,lon) : null;
    166                 primitive = new HistoryNode(
    167                         id,version,visible,user,changesetId,timestamp,coor
    168                 );
    169 
    170             } else if (type.equals(OsmPrimitiveType.WAY)) {
    171                 primitive = new HistoryWay(
    172                         id,version,visible,user,changesetId,timestamp
    173                 );
    174             }if (type.equals(OsmPrimitiveType.RELATION)) {
    175                 primitive = new HistoryRelation(
    176                         id,version,visible,user,changesetId,timestamp
    177                 );
    178             }
    179             return primitive;
    180         }
    181 
    182         protected void startNode(Attributes atts) throws SAXException {
    183             currentPrimitive= createPrimitive(atts, OsmPrimitiveType.NODE);
    184         }
    185 
    186         protected void startWay(Attributes atts) throws SAXException {
    187             currentPrimitive= createPrimitive(atts, OsmPrimitiveType.WAY);
    188         }
    189         protected void startRelation(Attributes atts) throws SAXException {
    190             currentPrimitive= createPrimitive(atts, OsmPrimitiveType.RELATION);
    191         }
    192 
    193         protected void handleTag(Attributes atts) throws SAXException {
    194             String key= getMandatoryAttributeString(atts, "k");
    195             String value= getMandatoryAttributeString(atts, "v");
    196             currentPrimitive.put(key,value);
    197         }
    198 
    199         protected void handleNodeReference(Attributes atts) throws SAXException {
    200             long ref = getMandatoryAttributeLong(atts, "ref");
    201             ((HistoryWay)currentPrimitive).addNode(ref);
    202         }
    203 
    204         protected void handleMember(Attributes atts) throws SAXException {
    205             long ref = getMandatoryAttributeLong(atts, "ref");
    206             String v = getMandatoryAttributeString(atts, "type");
    207             OsmPrimitiveType type = null;
    208             try {
    209                 type = OsmPrimitiveType.fromApiTypeName(v);
    210             } catch(IllegalArgumentException e) {
    211                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type OsmPrimitiveType. Got ''{1}''.", "type", v));
    212             }
    213             String role = getMandatoryAttributeString(atts, "role");
    214             RelationMemberData member = new RelationMemberData(role, type,ref);
    215             ((HistoryRelation)currentPrimitive).addMember(member);
     44            throw new OsmDataParsingException(e).rememberLocation(locator);
    21645        }
    21746
    21847        @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
    219             if (qName.equals("node")) {
    220                 startNode(atts);
    221             } else if (qName.equals("way")) {
    222                 startWay(atts);
    223             } else if (qName.equals("relation")) {
    224                 startRelation(atts);
    225             } else if (qName.equals("tag")) {
    226                 handleTag(atts);
    227             } else if (qName.equals("nd")) {
    228                 handleNodeReference(atts);
    229             } else if (qName.equals("member")) {
    230                 handleMember(atts);
     48            if (super.doStartElement(qName, atts)) {
     49                // done
    23150            } else if (qName.equals("osmChange")) {
    23251                // do nothing
     
    282101
    283102    /**
    284      * Create a parser
     103     * Constructs a new {@code OsmChangesetContentParser}.
    285104     *
    286105     * @param source the input stream with the changeset content as XML document. Must not be null.
    287      * @throws IllegalArgumentException thrown if source is null.
     106     * @throws UnsupportedEncodingException if {@code UTF-8} charset is missing
     107     * @throws IllegalArgumentException if source is {@code null}.
    288108     */
    289109    public OsmChangesetContentParser(InputStream source) throws UnsupportedEncodingException {
    290110        CheckParameterUtil.ensureParameterNotNull(source, "source");
    291111        this.source = new InputSource(new InputStreamReader(source, "UTF-8"));
    292         data = new ChangesetDataSet();
    293112    }
    294113
     114    /**
     115     * Constructs a new {@code OsmChangesetContentParser}.
     116     *
     117     * @param source the input stream with the changeset content as XML document. Must not be null.
     118     * @throws IllegalArgumentException if source is {@code null}.
     119     */
    295120    public OsmChangesetContentParser(String source) {
    296121        CheckParameterUtil.ensureParameterNotNull(source, "source");
    297122        this.source = new InputSource(new StringReader(source));
    298         data = new ChangesetDataSet();
    299123    }
    300124
    301125    /**
    302      * Parses the content
     126     * Parses the content.
    303127     *
    304      * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE}
    305      * if null
     128     * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
    306129     * @return the parsed data
    307130     * @throws OsmDataParsingException thrown if something went wrong. Check for chained
  • trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java

    r6090 r6201  
    77import java.io.InputStream;
    88import java.io.InputStreamReader;
    9 import java.util.Date;
    109
    1110import javax.xml.parsers.ParserConfigurationException;
    1211import javax.xml.parsers.SAXParserFactory;
    1312
    14 import org.openstreetmap.josm.data.coor.LatLon;
    15 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    16 import org.openstreetmap.josm.data.osm.RelationMemberData;
    17 import org.openstreetmap.josm.data.osm.User;
    1813import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
    19 import org.openstreetmap.josm.data.osm.history.HistoryNode;
    2014import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
    21 import org.openstreetmap.josm.data.osm.history.HistoryRelation;
    22 import org.openstreetmap.josm.data.osm.history.HistoryWay;
     15import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2316import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    24 import org.openstreetmap.josm.tools.DateUtils;
     17import org.openstreetmap.josm.tools.CheckParameterUtil;
    2518import org.xml.sax.Attributes;
    2619import org.xml.sax.InputSource;
    27 import org.xml.sax.Locator;
    2820import org.xml.sax.SAXException;
    29 import org.xml.sax.helpers.DefaultHandler;
    3021
    3122/**
     
    3526 * {@link org.openstreetmap.josm.data.osm.OsmPrimitive}s. We use objects derived from
    3627 * {@link HistoryOsmPrimitive} instead and we keep the data in a dedicated {@link HistoryDataSet}.
    37  *
     28 * @since 1670
    3829 */
    3930public class OsmHistoryReader {
     
    4233    private final HistoryDataSet data;
    4334
    44     // FIXME: this class has many similarities with OsmChangesetContentParser.Parser and should be merged
    45     private class Parser extends DefaultHandler {
    46 
    47         /** the current primitive to be read */
    48         private HistoryOsmPrimitive current;
    49         private Locator locator;
    50 
    51         @Override
    52         public void setDocumentLocator(Locator locator) {
    53             this.locator = locator;
    54         }
     35    private class Parser extends AbstractParser {
    5536
    5637        protected String getCurrentPosition() {
     
    6142
    6243        protected void throwException(String message) throws SAXException {
    63             throw new SAXException(
    64                     getCurrentPosition()
    65                     +   message
    66             );
     44            throw new SAXException(getCurrentPosition() + message);
    6745        }
    6846
    69         protected long getMandatoryAttributeLong(Attributes attr, String name) throws SAXException{
    70             String v = attr.getValue(name);
    71             if (v == null) {
    72                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    73             }
    74             Long l = 0L;
    75             try {
    76                 l = Long.parseLong(v);
    77             } catch(NumberFormatException e) {
    78                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
    79             }
    80             if (l < 0) {
    81                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
    82             }
    83             return l;
    84         }
    85 
    86         protected Long getAttributeLong(Attributes attr, String name) throws SAXException {
    87             String v = attr.getValue(name);
    88             if (v == null)
    89                 return null;
    90             Long l = null;
    91             try {
    92                 l = Long.parseLong(v);
    93             } catch(NumberFormatException e) {
    94                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
    95             }
    96             if (l < 0) {
    97                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
    98             }
    99             return l;
    100         }
    101 
    102         protected Double getAttributeDouble(Attributes attr, String name) throws SAXException{
    103             String v = attr.getValue(name);
    104             if (v == null) {
    105                 return null;
    106             }
    107             double d = 0.0;
    108             try {
    109                 d = Double.parseDouble(v);
    110             } catch(NumberFormatException e) {
    111                 throwException(tr("Illegal value for attribute ''{0}'' of type double. Got ''{1}''.", name, v));
    112             }
    113             return d;
    114         }
    115 
    116         protected String getMandatoryAttributeString(Attributes attr, String name) throws SAXException{
    117             String v = attr.getValue(name);
    118             if (v == null) {
    119                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    120             }
    121             return v;
    122         }
    123 
    124         protected boolean getMandatoryAttributeBoolean(Attributes attr, String name) throws SAXException{
    125             String v = attr.getValue(name);
    126             if (v == null) {
    127                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
    128             }
    129             if ("true".equals(v)) return true;
    130             if ("false".equals(v)) return false;
    131             throwException(tr("Illegal value for mandatory attribute ''{0}'' of type boolean. Got ''{1}''.", name, v));
    132             // not reached
    133             return false;
    134         }
    135 
    136         protected  HistoryOsmPrimitive createPrimitive(Attributes atts, OsmPrimitiveType type) throws SAXException {
    137             long id = getMandatoryAttributeLong(atts,"id");
    138             long version = getMandatoryAttributeLong(atts,"version");
    139             long changesetId = getMandatoryAttributeLong(atts,"changeset");
    140             boolean visible= getMandatoryAttributeBoolean(atts, "visible");
    141             Long uid = getAttributeLong(atts, "uid");
    142             String userStr = atts.getValue("user");
    143             User user;
    144             if (userStr != null) {
    145                 if (uid != null) {
    146                     user = User.createOsmUser(uid, userStr);
    147                 } else {
    148                     user = User.createLocalUser(userStr);
    149                 }
    150             } else {
    151                 user = User.getAnonymous();
    152             }
    153             String v = getMandatoryAttributeString(atts, "timestamp");
    154             Date timestamp = DateUtils.fromString(v);
    155             HistoryOsmPrimitive primitive = null;
    156             if (type.equals(OsmPrimitiveType.NODE)) {
    157                 Double lat = getAttributeDouble(atts, "lat");
    158                 Double lon = getAttributeDouble(atts, "lon");
    159                 LatLon coord = (lat != null && lon != null) ? new LatLon(lat,lon) : null;
    160                 primitive = new HistoryNode(
    161                         id,version,visible,user,changesetId,timestamp,coord
    162                 );
    163 
    164             } else if (type.equals(OsmPrimitiveType.WAY)) {
    165                 primitive = new HistoryWay(
    166                         id,version,visible,user,changesetId,timestamp
    167                 );
    168             }if (type.equals(OsmPrimitiveType.RELATION)) {
    169                 primitive = new HistoryRelation(
    170                         id,version,visible,user,changesetId,timestamp
    171                 );
    172             }
    173             return primitive;
    174         }
    175 
    176         protected void startNode(Attributes atts) throws SAXException {
    177             current= createPrimitive(atts, OsmPrimitiveType.NODE);
    178         }
    179 
    180         protected void startWay(Attributes atts) throws SAXException {
    181             current= createPrimitive(atts, OsmPrimitiveType.WAY);
    182         }
    183         protected void startRelation(Attributes atts) throws SAXException {
    184             current= createPrimitive(atts, OsmPrimitiveType.RELATION);
    185         }
    186 
    187         protected void handleTag(Attributes atts) throws SAXException {
    188             String key= getMandatoryAttributeString(atts, "k");
    189             String value= getMandatoryAttributeString(atts, "v");
    190             current.put(key,value);
    191         }
    192 
    193         protected void handleNodeReference(Attributes atts) throws SAXException {
    194             long ref = getMandatoryAttributeLong(atts, "ref");
    195             ((HistoryWay)current).addNode(ref);
    196         }
    197 
    198         protected void handleMember(Attributes atts) throws SAXException {
    199             long ref = getMandatoryAttributeLong(atts, "ref");
    200             String v = getMandatoryAttributeString(atts, "type");
    201             OsmPrimitiveType type = null;
    202             try {
    203                 type = OsmPrimitiveType.fromApiTypeName(v);
    204             } catch(IllegalArgumentException e) {
    205                 throwException(tr("Illegal value for mandatory attribute ''{0}'' of type OsmPrimitiveType. Got ''{1}''.", "type", v));
    206             }
    207             String role = getMandatoryAttributeString(atts, "role");
    208             RelationMemberData member = new RelationMemberData(role, type,ref);
    209             ((HistoryRelation)current).addMember(member);
    210         }
    211 
    212         @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
    213             if (qName.equals("node")) {
    214                 startNode(atts);
    215             } else if (qName.equals("way")) {
    216                 startWay(atts);
    217             } else if (qName.equals("relation")) {
    218                 startRelation(atts);
    219             } else if (qName.equals("tag")) {
    220                 handleTag(atts);
    221             } else if (qName.equals("nd")) {
    222                 handleNodeReference(atts);
    223             } else if (qName.equals("member")) {
    224                 handleMember(atts);
    225             }
     47        @Override
     48        public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
     49            doStartElement(qName, atts);
    22650        }
    22751
     
    23155                    || qName.equals("way")
    23256                    || qName.equals("relation")) {
    233                 data.put(current);
     57                data.put(currentPrimitive);
    23458            }
    23559        }
    23660    }
    23761
     62    /**
     63     * Constructs a new {@code OsmHistoryReader}.
     64     *
     65     * @param source the input stream with the history content as XML document. Must not be null.
     66     * @throws IllegalArgumentException if source is {@code null}.
     67     */
    23868    public OsmHistoryReader(InputStream source) {
     69        CheckParameterUtil.ensureParameterNotNull(source, "source");
    23970        this.in = source;
    24071        this.data = new HistoryDataSet();
    24172    }
    24273
     74    /**
     75     * Parses the content.
     76     * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
     77     * @return the parsed data
     78     * @throws SAXException If any SAX errors occur during processing.
     79     * @throws IOException If any IO errors occur.
     80     */
    24381    public HistoryDataSet parse(ProgressMonitor progressMonitor) throws SAXException, IOException {
    24482        InputSource inputSource = new InputSource(new InputStreamReader(in, "UTF-8"));
     
    24684        try {
    24785            SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new Parser());
    248         } catch (ParserConfigurationException e1) {
    249             e1.printStackTrace(); // broken SAXException chaining
    250             throw new SAXException(e1);
     86        } catch (ParserConfigurationException e) {
     87            e.printStackTrace(); // broken SAXException chaining
     88            throw new SAXException(e);
    25189        } finally {
    25290            progressMonitor.finishTask();
Note: See TracChangeset for help on using the changeset viewer.