ca.qhrtech.services.implementations.BGGServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for ca.qhrtech.services.implementations.BGGServiceImpl.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ca.qhrtech.services.implementations;

import ca.qhrtech.entities.Game;
import ca.qhrtech.entities.bgg.GameStub;
import ca.qhrtech.entities.bgg.LinkQuery;
import ca.qhrtech.entities.bgg.SearchQuery;
import ca.qhrtech.services.interfaces.BGGService;
import ca.qhrtech.services.interfaces.GameService;
import ca.qhrtech.utilities.Converter;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

/**
 *
 * @author bryan.bergen
 */
@Service("bggService")
public class BGGServiceImpl implements BGGService {

    private static final String BASE_BGG_URL = "http://boardgamegeek.com/xmlapi2";
    private static final String END_POINT_SEARCH = "/search";
    private static final String END_POINT_LINK = "/thing";

    @Autowired
    private GameService gameService;

    @Autowired
    private Converter<LinkQuery, Game> linkConverter;

    @Override
    public List<Game> findLinkableGames(long id) {
        Game game = gameService.findGameById(id);
        if (game == null) {
            return Collections.EMPTY_LIST;
        }
        return consumeBggApi(buildUriForQuery(game), SearchQuery.class, new SearchConverter());
    }

    @Override
    public Game linkGame(long bglId, long bggId) {
        Game game = gameService.findGameById(bglId);
        if (game == null) {
            return null;
        }
        game = consumeBggApi(buildUriForLink(bggId), LinkQuery.class, linkConverter);
        game.setId(bglId);
        gameService.updateGame(game);
        return game;
    }

    /**
     * Consumes a BGG XML API End Point and converts the response to a usable
     * POJO using the passed converter
     *
     * @param <T> - Class the response should expect
     * @param <K> - Class the converter produces
     * @param uri - end point
     * @param t - Class the response should expect
     * @param converter - converts T to K
     * @return - results of the conversion
     */
    private <T, K> K consumeBggApi(URI uri, Class<T> t, Converter<T, K> converter) {
        RestTemplate template = new RestTemplate();
        ResponseEntity<T> response;
        response = template.exchange(uri, HttpMethod.GET, buildXmlHttpHeader(), t);
        return converter.convert(response.getBody());
    }

    private HttpEntity<?> buildXmlHttpHeader() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", MediaType.APPLICATION_XML_VALUE);
        return new HttpEntity<>(headers);
    }

    private URI buildUriForLink(long bggId) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(BASE_BGG_URL + END_POINT_LINK);
        builder.queryParam("id", bggId);
        builder.queryParam("type", "boardgame");
        return builder.build().encode().toUri();
    }

    private URI buildUriForQuery(Game game) {
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(BASE_BGG_URL + END_POINT_SEARCH);
        builder.queryParam("query", game.getName());
        builder.queryParam("type", "boardgame");
        return builder.build().encode().toUri();
    }

    private static class SearchConverter implements Converter<SearchQuery, List<Game>> {

        @Override
        public List<Game> convert(SearchQuery query) {
            List<Game> games = new ArrayList<>();
            for (GameStub bggGame : query.getGames()) {
                if (bggGame.getType().equals("boardgame")) {
                    Game game = new Game();
                    game.setBggId(bggGame.getId());
                    game.setName(bggGame.getName().getValue());
                    game.setYearPublished(bggGame.getYear().getValue());
                    games.add(game);
                }
            }
            return games;
        }
    }

}