001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.io;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.io.InputStream;
007    import java.util.LinkedList;
008    import java.util.List;
009    
010    import javax.xml.parsers.DocumentBuilderFactory;
011    import javax.xml.xpath.XPath;
012    import javax.xml.xpath.XPathConstants;
013    import javax.xml.xpath.XPathException;
014    import javax.xml.xpath.XPathFactory;
015    
016    import org.openstreetmap.josm.data.coor.LatLon;
017    import org.openstreetmap.josm.data.osm.DataSet;
018    import org.openstreetmap.josm.data.osm.UserInfo;
019    import org.openstreetmap.josm.gui.progress.ProgressMonitor;
020    import org.openstreetmap.josm.tools.DateUtils;
021    import org.w3c.dom.Document;
022    import org.w3c.dom.Node;
023    import org.w3c.dom.NodeList;
024    
025    public class OsmServerUserInfoReader extends OsmServerReader {
026    
027        static protected String getAttribute(Node node, String name) {
028            return node.getAttributes().getNamedItem(name).getNodeValue();
029        }
030    
031        static public  UserInfo buildFromXML(Document document) throws OsmDataParsingException{
032            try {
033                XPathFactory factory = XPathFactory.newInstance();
034                XPath xpath = factory.newXPath();
035                UserInfo userInfo = new UserInfo();
036                Node xmlNode = (Node)xpath.compile("/osm/user[1]").evaluate(document, XPathConstants.NODE);
037                if ( xmlNode== null)
038                    throw new OsmDataParsingException(tr("XML tag <user> is missing."));
039    
040                // -- id
041                String v = getAttribute(xmlNode, "id");
042                if (v == null)
043                    throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "id", "user"));
044                try {
045                    userInfo.setId(Integer.parseInt(v));
046                } catch(NumberFormatException e) {
047                    throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "id", "user", v));
048                }
049                // -- display name
050                v = getAttribute(xmlNode, "display_name");
051                userInfo.setDisplayName(v);
052                // -- account_created
053                v = getAttribute(xmlNode, "account_created");
054                if (v!=null) {
055                    userInfo.setAccountCreated(DateUtils.fromString(v));
056                }
057                // -- description
058                xmlNode = (Node)xpath.compile("/osm/user[1]/description[1]/text()").evaluate(document, XPathConstants.NODE);
059                if (xmlNode != null) {
060                    userInfo.setDescription(xmlNode.getNodeValue());
061                }
062                // -- home
063                xmlNode = (Node)xpath.compile("/osm/user[1]/home").evaluate(document, XPathConstants.NODE);
064                if (xmlNode != null) {
065                    v = getAttribute(xmlNode, "lat");
066                    if (v == null)
067                        throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "lat", "home"));
068                    double lat;
069                    try {
070                        lat = Double.parseDouble(v);
071                    } catch(NumberFormatException e) {
072                        throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "lat", "home", v));
073                    }
074    
075                    v = getAttribute(xmlNode, "lon");
076                    if (v == null)
077                        throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "lon", "home"));
078                    double lon;
079                    try {
080                        lon = Double.parseDouble(v);
081                    } catch(NumberFormatException e) {
082                        throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "lon", "home", v));
083                    }
084    
085                    v = getAttribute(xmlNode, "zoom");
086                    if (v == null)
087                        throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "zoom", "home"));
088                    int zoom;
089                    try {
090                        zoom = Integer.parseInt(v);
091                    } catch(NumberFormatException e) {
092                        throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "zoom", "home", v));
093                    }
094                    userInfo.setHome(new LatLon(lat,lon));
095                    userInfo.setHomeZoom(zoom);
096                }
097    
098                // -- language list
099                NodeList xmlNodeList = (NodeList)xpath.compile("/osm/user[1]/languages[1]/lang/text()").evaluate(document, XPathConstants.NODESET);
100                if (xmlNodeList != null) {
101                    List<String> languages = new LinkedList<String>();
102                    for (int i=0; i < xmlNodeList.getLength(); i++) {
103                        languages.add(xmlNodeList.item(i).getNodeValue());
104                    }
105                    userInfo.setLanguages(languages);
106                }
107                return userInfo;
108            } catch(XPathException e) {
109                throw new OsmDataParsingException(e);
110            }
111        }
112    
113        public OsmServerUserInfoReader() {
114            setDoAuthenticate(true);
115        }
116    
117        @Override
118        public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
119            // not implemented
120            return null;
121        }
122    
123        public UserInfo fetchUserInfo(ProgressMonitor monitor) throws OsmTransferException {
124            try {
125                monitor.beginTask("");
126                monitor.indeterminateSubTask(tr("Reading user info ..."));
127                InputStream in = getInputStream("user/details", monitor.createSubTaskMonitor(1, true));
128                return buildFromXML(
129                        DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in)
130                );
131            } catch(OsmTransferException e) {
132                throw e;
133            } catch(Exception e) {
134                throw new OsmTransferException(e);
135            } finally {
136                monitor.finishTask();
137            }
138        }
139    }