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.util.HashMap;
007import java.util.Map;
008
009import javax.xml.xpath.XPath;
010import javax.xml.xpath.XPathConstants;
011import javax.xml.xpath.XPathException;
012import javax.xml.xpath.XPathFactory;
013
014import org.openstreetmap.josm.data.osm.DataSet;
015import org.openstreetmap.josm.gui.progress.ProgressMonitor;
016import org.openstreetmap.josm.tools.XmlParsingException;
017import org.w3c.dom.Document;
018import org.w3c.dom.Node;
019import org.w3c.dom.NodeList;
020
021/**
022 * Download and parse preferences of the logged in user (OSM API v0.6 "/user/preferences").
023 * @see <a href="https://wiki.openstreetmap.org/wiki/API_v0.6#Preferences_of_the_logged-in_user">/user/preferences</a>
024 * @since 12502
025 */
026public class OsmServerUserPreferencesReader extends OsmServerReader {
027
028    /**
029     * Parses the given XML data and returns the associated user preferences.
030     * @param document The XML contents
031     * @return The user preferences
032     * @throws XmlParsingException if parsing goes wrong
033     */
034    public static Map<String, String> buildFromXML(Document document) throws XmlParsingException {
035        try {
036            XPath xpath = XPathFactory.newInstance().newXPath();
037            Map<String, String> result = new HashMap<>();
038
039            // -- preferences
040            NodeList xmlNodeList = (NodeList) xpath.compile("/osm/preferences/preference").evaluate(document, XPathConstants.NODESET);
041            if (xmlNodeList != null) {
042                for (int i = 0; i < xmlNodeList.getLength(); i++) {
043                    Node xmlNode = xmlNodeList.item(i);
044                    String k = getAttribute(xmlNode, "k");
045                    if (k == null)
046                        throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "k", "preference"));
047                    String v = getAttribute(xmlNode, "v");
048                    if (v == null)
049                        throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "v", "preference"));
050                    result.put(k, v);
051                }
052            }
053
054            return result;
055        } catch (XPathException e) {
056            throw new XmlParsingException(e);
057        }
058    }
059
060    /**
061     * Constructs a new {@code OsmServerUserInfoReader}.
062     */
063    public OsmServerUserPreferencesReader() {
064        setDoAuthenticate(true);
065    }
066
067    @Override
068    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
069        // not implemented
070        return null;
071    }
072
073    /**
074     * Fetches user preferences, without explicit reason.
075     * @param monitor The progress monitor
076     * @return The user preferences
077     * @throws OsmTransferException if something goes wrong
078     */
079    public Map<String, String> fetchUserPreferences(ProgressMonitor monitor) throws OsmTransferException {
080        return fetchUserPreferences(monitor, null);
081    }
082
083    /**
084     * Fetches user info, with an explicit reason.
085     * @param monitor The progress monitor
086     * @param reason The reason to show on console. Can be {@code null} if no reason is given
087     * @return The user info
088     * @throws OsmTransferException if something goes wrong
089     */
090    public Map<String, String> fetchUserPreferences(ProgressMonitor monitor, String reason) throws OsmTransferException {
091        return fetchData("user/preferences", tr("Reading user preferences ..."),
092                OsmServerUserPreferencesReader::buildFromXML, monitor, reason);
093    }
094}