package com.transformuk.bdt.service; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.transformuk.bdt.mapit.domain.Entity; import com.transformuk.bdt.mapit.domain.MapItPartialPostCode; import com.transformuk.bdt.mapit.domain.MapItPointResponse; import com.transformuk.bdt.mapit.domain.MapItPostCode; import com.transformuk.bdt.util.MapItCouncilCodes; import com.transformuk.bdt.util.StaticReferences; @Service @Configuration @PropertySource(value = "classpath:conf.properties") public class MapItServiceImpl implements IMapItService { private static final String COMMA = ","; @Autowired CustomObjectMapper mapper; @Autowired MapItClientService mapItClient; @Value("${mapit.postcode.api.url}") private String mapItApiUrl; @Value("${mapit.partial.postcode.api.url}") private String mapItPartialApiUrl; @Value("${mapit.point.api.url}") private String mapItPointApiUrl; private static final Logger logger = Logger.getLogger(MapItServiceImpl.class); @Override public ResponseEntity<String> getMapItDataForFullPostCode(String postCode) { logger.debug("Calling Mapit url full code: "+mapItApiUrl+" with postcode:"+postCode); return mapItClient.callMapIt(mapItApiUrl, postCode); } @Override public ResponseEntity<String> getMapItDataForPartialPostCode(String postCode) { logger.debug("Calling Mapit url partial code: "+mapItApiUrl+" with postcode:"+postCode); return mapItClient.callMapIt(mapItPartialApiUrl, postCode); } @Override public ResponseEntity<String> getMapItPointDataForPartialPostCode(String easting, String northing) { //custom url StringBuilder url = new StringBuilder(); url.append(mapItPointApiUrl).append(easting).append(COMMA).append(northing); return mapItClient.callMapIt(url.toString()); } /** * Fetches values for partial post code * @param json response from mapit post code * @return MapItPostCode containing the easting and northing values */ @Override public MapItPartialPostCode convertDataFromPartialPostCode(String jsonResponse) throws JsonParseException, JsonMappingException, IOException { return mapper.readValue(jsonResponse, MapItPartialPostCode.class); } /** * Fetches point values based on easting and northing of a partial post code * @param json response from mapit post code * @return ResponseEntity containing json response with gss list, name etc. */ @Override public ResponseEntity<String> getDataFromPointApi(MapItPartialPostCode mapItResponse) throws JsonParseException, JsonMappingException, IOException { String easting = mapItResponse.getEasting().toString(); String northing = mapItResponse.getNorthing().toString(); return getMapItPointDataForPartialPostCode(easting, northing); } /** * Returns a map of: all not null gss, name i.e. location (for EUR) list * and councilList for a given json input * @param isPartialPostCode * @param json response from mapit * @return Map containing gss list, name i.e. location for eur and council */ @Override public Map<String, List<String>> getGssNamesFromPostCodeResponse( String jsonResponse, boolean isPartialPostCode) throws JsonParseException, JsonMappingException, IOException { List<Entity> entities = null; if (isPartialPostCode) { //for point api partial post code there are no areas direct entities MapItPointResponse mapItPostCodeResponse = mapper.readValue(jsonResponse, MapItPointResponse.class); entities = mapItPostCodeResponse.getEntityList(); } else { MapItPostCode mapItPostCodeResponse = mapper.readValue(jsonResponse, MapItPostCode.class); entities = mapItPostCodeResponse.getAreas().getEntityList(); } List<Entity> entityList = new ArrayList<Entity>(); for (Entity item : entities) { //dynamic mapping entityList.add(mapper.convertValue(item, Entity.class)); } //holds all not null gss codes returned from mapit List<String> gssList = new ArrayList<String>(); //holds the 'name' list if the type is EUR //(special case as the name from EUR will be used as 'location' for search query List<String> eurNameList = new ArrayList<String>(); //holds the country name if the type is EUR List<String> eurCountryNameList = new ArrayList<String>(); //holds the code for council List<String> councilCodeList = new ArrayList<String>(); for (Entity item : entityList) { if (item.getCodes().getGss() != null) { //only add gss's which are not null gssList.add(item.getCodes().getGss()); } //if the type is eur then save its name String type = item.getType(); //should only contain one EUR element if (StringUtils.equalsIgnoreCase(type, StaticReferences.EUR)) { eurNameList.add(item.getName()); eurCountryNameList.add(item.getCountryName()); } else if (containsCouncilCode(type)){ councilCodeList.add(item.getName()); } } Map<String, List<String>> gssNameMap = new HashMap<String, List<String>>(); gssNameMap.put(StaticReferences.GSS, gssList); gssNameMap.put(StaticReferences.NAMES, eurNameList); gssNameMap.put(StaticReferences.COUNTRY_NAME, eurCountryNameList); gssNameMap.put(StaticReferences.COUNCIL_CODE, councilCodeList); if (logger.isDebugEnabled()) { logger.debug("Found "+gssList.size()+" GSS codes"+" and "+eurNameList.size()+" Names for EUR"); } return gssNameMap; } @SuppressWarnings("unused") private boolean containsCouncilCode(String type) { MapItCouncilCodes councilCode; try { councilCode = MapItCouncilCodes.valueOf(type.toUpperCase()); return true; } catch (IllegalArgumentException ex) { return false; } // for (MapItCouncilCodes councilCode : MapItCouncilCodes.values()) { // if (StringUtils.equalsIgnoreCase(councilCode.name(),type)) { // return true; // } // } // // return false; } }