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