Java tutorial
/* * 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; } } }