fm.last.lastfmlive.service.LastfmFacade.java Source code

Java tutorial

Introduction

Here is the source code for fm.last.lastfmlive.service.LastfmFacade.java

Source

/*
 * Copyright 2012 Last.fm
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package fm.last.lastfmlive.service;

import java.util.List;
import java.util.Map;

import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.xml.xpath.Jaxp13XPathTemplate;
import org.springframework.xml.xpath.NodeMapper;
import org.springframework.xml.xpath.XPathOperations;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

import fm.last.lastfmlive.data.Artist;
import fm.last.lastfmlive.data.Track;
import fm.last.lastfmlive.data.User;

@Repository
public class LastfmFacade {

    private static Logger log = LoggerFactory.getLogger(LastfmFacade.class);

    private static final String wsPrefix = "http://ws.audioscrobbler.com/2.0/?method=";
    private final String apiKey;

    private final XPathOperations xpathTemplate = new Jaxp13XPathTemplate();

    @Autowired
    public LastfmFacade(@Value("${lastfmlive.apiKey}") String apiKey) {
        this.apiKey = apiKey;
    }

    public List<Artist> getTopArtists(String userName) {
        log.info("Getting top artists for user {}", userName);

        RestTemplate restTemplate = new RestTemplate();
        String methodString = "user.gettopartists&user={user}&api_key={apiKey}";
        Source topArtistsXml = restTemplate.getForObject(wsPrefix + methodString, Source.class, userName, apiKey);
        List<Map<String, String>> output = xpathTemplate.evaluate("//artist", topArtistsXml,
                new MapNodeMapper("name", "playcount", "image[@size='large']"));

        log.info("Found {} top artists", output.size());
        return Lists.transform(output, artistFromMap);
    }

    public List<Track> getTopTracks(String userName) {
        log.info("Getting top tracks for user {}", userName);

        RestTemplate restTemplate = new RestTemplate();
        String methodString = "user.gettoptracks&user={user}&api_key={apiKey}";
        Source topArtistsXml = restTemplate.getForObject(wsPrefix + methodString, Source.class, userName, apiKey);
        List<Track> output = xpathTemplate.evaluate("//track", topArtistsXml, new NodeMapper<Track>() {
            public Track mapNode(Node node, int nodeIndex) throws DOMException {
                Source src = new DOMSource(node);
                try {
                    String title = xpathTemplate.evaluateAsNodeList("name", src).get(0).getTextContent();
                    String artist = xpathTemplate.evaluateAsNodeList("artist/name", src).get(0).getTextContent();
                    return new Track(artist, title);
                } catch (Exception e) {
                    return null;
                }
            }
        });

        log.info("Found {} top tracks", output.size());
        return output;
    }

    public User getUserInfo(String userName) {
        log.info("Getting user info for user {}", userName);

        RestTemplate restTemplate = new RestTemplate();
        String methodString = "user.getinfo&user={user}&api_key={apiKey}";
        try {
            Source topArtistsXml = restTemplate.getForObject(wsPrefix + methodString, Source.class, userName,
                    apiKey);
            List<Map<String, String>> output = xpathTemplate.evaluate("//user", topArtistsXml,
                    new MapNodeMapper("name", "realname", "image[@size='large']", "age", "gender"));
            if (output.size() == 0) {
                log.warn("User info not found.");
                return null;
            }

            log.info("Found user info: {}", output);
            return userFromMap.apply(output.get(0));
        } catch (HttpClientErrorException e) {
            log.warn("User not found '{}'", userName);
            return null;
        }

    }

    public List<String> getTopTags(String artistName) {
        log.info("Getting top tags for artist {}", artistName);

        RestTemplate restTemplate = new RestTemplate();
        String methodString = "artist.gettoptags&artist={artist}&api_key={apiKey}";
        Source topArtistsXml = restTemplate.getForObject(wsPrefix + methodString, Source.class, artistName, apiKey);
        List<Map<String, String>> output = xpathTemplate.evaluate("//tag", topArtistsXml,
                new MapNodeMapper("name"));

        log.info("Found {} tags", output.size());
        return Lists.transform(output, tagFromMap);
    }

    private static Function<Map<String, String>, Artist> artistFromMap = new Function<Map<String, String>, Artist>() {
        public Artist apply(Map<String, String> arg0) {
            if (!arg0.containsKey("name")) {
                throw new IllegalArgumentException("Map must contain 'name' key");
            }
            Artist a = new Artist();
            a.setName(arg0.get("name"));
            a.setImageUrl(arg0.get("image"));
            a.setUrl(arg0.get("url"));
            return a;
        }
    };

    private static Function<Map<String, String>, User> userFromMap = new Function<Map<String, String>, User>() {
        public User apply(Map<String, String> map) {
            if (!map.containsKey("name")) {
                throw new IllegalArgumentException("Map must contain 'name' key");
            }
            User u = new User(map.get("name"));
            u.setImageUrl(map.get("image"));
            u.setUrl(map.get("url"));
            u.setAge(map.get("age"));
            u.setRealName(map.get("realname"));
            u.setGender(map.get("gender"));
            return u;
        }
    };

    private static Function<Map<String, String>, String> tagFromMap = new Function<Map<String, String>, String>() {

        public String apply(Map<String, String> arg0) {
            return arg0.get("name");
        }
    };

}