Commit e5f4a015 authored by Deepak Prabhakar's avatar Deepak Prabhakar

Refactored PostcodeLookup. Got rid of inner classes. code cleaning.

parent a4d1e035
......@@ -17,6 +17,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
......
package com.postcode.io.initializers;
import java.net.MalformedURLException;
import java.net.URL;
import org.codehaus.plexus.util.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import com.postcode.io.PostCodeDetails;
import com.postcode.io.json.JsonFetcher;
/**
* @author Deepak
*
*/
public class Postcode {
private static final String LOOKUP_URL = "http://api.postcodes.io/postcodes/";
private String postcode;
private String[] postcodes;
private JSONObject json;
public Postcode(String postcode) {
this.postcode = postcode;
}
public Postcode(String[] postcodes) {
this.postcodes = postcodes;
createJsonPostcodes(this.postcodes);
}
private void createJsonPostcodes(String[] postcodes) {
JSONObject json = new JSONObject();
JSONArray jsonArray = new JSONArray();
for (String string : postcodes) {
jsonArray.put(string);
}
this.json = json.put("postcodes", jsonArray);
}
/**
* Get JSON for the given {@link #postcode} / {@link #postcodes}
*
* @return
* @throws Exception
*/
public JSONObject asJson() throws Exception {
if (!StringUtils.isEmpty(postcode)) {
return JsonFetcher.urlToJson(new URL(LOOKUP_URL.toString().concat(postcode)));
} else if (json != null) {
return JsonFetcher.postURLToJson(new URL(LOOKUP_URL.toString()), json);
} else {
throw new IllegalArgumentException("postcode/postcodes are mandatory");
}
}
/**
* Use this to create {@link PostCodeDetails}<br/>
* Pass this to {@link PostCodeDetails#generate}
*
* @return
* @throws MalformedURLException
*/
public PostcodeLookup build() throws MalformedURLException {
if (postcode != null) {
return new PostcodeLookup(new URL(LOOKUP_URL.toString().concat(postcode)), postcode, postcodes);
} else if (postcode == null && postcodes != null) {
return new PostcodeLookup(new URL(LOOKUP_URL.toString()), postcode, postcodes);
} else {
throw new IllegalArgumentException("postcode/postcodes are mandatory");
}
}
}
package com.postcode.io.initializers;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.codehaus.plexus.util.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import com.postcode.io.PostCode;
import com.postcode.io.json.JsonFetcher;
import com.postcode.io.initializers.ReverseGeocoding.Reverse;
/**
* Lookup a postcode
......@@ -18,15 +13,13 @@ import com.postcode.io.json.JsonFetcher;
*/
public class PostcodeLookup {
private static final String LOOKUP_URL = "http://api.postcodes.io/postcodes/";
private String postcode;
private String[] postcodes;
private String url;
private PostcodeLookup(URL url, String postcode, String[] postcodes) {
PostcodeLookup(URL url, String postcode, String[] postcodes) {
this.url = url.toString();
this.postcode = postcode;
this.postcodes = postcodes;
......@@ -36,79 +29,55 @@ public class PostcodeLookup {
return postcode;
}
public String[] getPostcodes() {
return postcodes;
}
public String getUrl() {
return url;
}
/**
* {@link PostcodeLookup} {@link Builder} Class
* Lookup a postcode. Returns all available data if found. Returns 404 if postcode does not
* exist.
*
* @author Deepak
*
* @param postCode
* @return
*/
public static class Builder {
private String postcode;
private String[] postcodes;
private JSONObject json;
public Builder() {
}
/**
* Use this to create {@link PostCode}<br/>
* Pass this to {@link PostCode#generate}
*
* @return
* @throws MalformedURLException
*/
public PostcodeLookup build() throws MalformedURLException {
return new PostcodeLookup(new URL(LOOKUP_URL.toString().concat(postcode)), postcode, postcodes);
}
public JSONObject asJson() throws Exception {
if (!StringUtils.isEmpty(postcode)) {
return JsonFetcher.urlToJson(new URL(LOOKUP_URL.toString().concat(postcode)));
} else if (json != null) {
return JsonFetcher.postURLToJson(new URL(LOOKUP_URL.toString()), json);
} else {
throw new IllegalArgumentException();
}
}
public static Postcode postcode(String postCode) {
return new Postcode(postCode);
}
/**
* Use if information required is for only one {@link PostCode}
*
* @param postcode
* @return
*/
public Builder postcode(String postcode) {
this.postcode = postcode;
return this;
}
/**
* Returns a list of matching postcodes and respective available data.
*
* @param postcodes
* Postcodes to Lookup (Max Limit is 100. Default is 10)
* @return
*/
public static Postcode postcodes(String[] postcodes) {
return new Postcode(postcodes);
}
/**
* Use if information required is for multiple {@link PostCode}
*
* @param postcodes
* @return
*/
public Builder postcodes(String[] postcodes) {
this.postcodes = postcodes;
createJsonPostcodes(postcodes);
return this;
}
/**
* Returns nearest postcodes for a given longitude and latitude.
*
* @param longitude
* @param latitude
* @return
*/
public static ReverseGeocoding reverseGeocoding(Double longitude, Double latitude) {
return new ReverseGeocoding(longitude, latitude);
}
private void createJsonPostcodes(String[] postcodes) {
JSONObject json = new JSONObject();
JSONArray jsonArray = new JSONArray();
for (String string : postcodes) {
jsonArray.put(string);
}
this.json = json.put("postcodes", jsonArray);
}
/**
* Bulk translates geolocations into Postcodes. Accepts up to 100 geolocations.
*
* @param reverses
* @return
*/
public static ReverseGeocoding reverseGeocodings(List<Reverse> reverses) {
return new ReverseGeocoding(reverses);
}
}
package com.postcode.io.initializers;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import com.postcode.io.json.JsonFetcher;
/**
* @author Deepak
*
*/
public class ReverseGeocoding {
private static final String LOOKUP_URL = "http://api.postcodes.io/postcodes?";
private static Double longitude;
private static Double latitude;
private static int limit;
private static int radius;
private static boolean wideSearch;
private static JSONObject json;
private static List<Reverse> reverses = new ArrayList<>();
public ReverseGeocoding() {
}
public ReverseGeocoding(Double longitude, Double latitude) {
ReverseGeocoding.longitude = longitude;
ReverseGeocoding.latitude = latitude;
}
public ReverseGeocoding limit(int limit) {
ReverseGeocoding.limit = limit;
return this;
}
public ReverseGeocoding(List<Reverse> reverses) {
ReverseGeocoding.reverses = reverses;
ReverseGeocoding.json = createGeocodings(ReverseGeocoding.reverses);
}
public ReverseGeocoding radius(int radius) {
ReverseGeocoding.radius = radius;
return this;
}
public ReverseGeocoding json(JSONObject json) {
ReverseGeocoding.json = json;
return this;
}
public ReverseGeocoding json(List<Reverse> reverses) {
ReverseGeocoding.reverses = reverses;
ReverseGeocoding.json = createGeocodings(ReverseGeocoding.reverses);
return this;
}
/**
* (not required) Search up to 20km radius, but subject to a maximum of 10 results. Since
* lookups over a wide area can be very expensive, we've created this method to allow you choose
* to make the trade off between search radius and number of results. Defaults to false. When
* enabled, radius and limits over 10 are ignored.
*
* @param wideSearch
* @return
*/
public ReverseGeocoding wideSearch(boolean wideSearch) {
ReverseGeocoding.wideSearch = wideSearch;
return this;
}
public JSONObject asjson() throws MalformedURLException, IOException {
String url = "";
url = url.concat("lon=").concat(String.valueOf(longitude));
url = url.concat("&lat=").concat(String.valueOf(latitude));
if (getLimit() != 0) {
url = url.concat("&limit=").concat(String.valueOf(limit));
}
if (getRadius() != 0) {
url = url.concat("&radius=").concat(String.valueOf(radius));
}
if (isWideSearch()) {
url = url.concat("&widesearch=").concat(String.valueOf(wideSearch));
}
if (json != null) {
return JsonFetcher.postURLToJson(new URL(LOOKUP_URL), json);
} else {
return JsonFetcher.urlToJson(new URL(LOOKUP_URL.concat(url)));
}
}
private JSONObject createGeocodings(List<Reverse> reverses) {
JSONObject json = new JSONObject();
JSONObject tempJson;
JSONArray jsonArray = new JSONArray();
for (Reverse reverse : reverses) {
tempJson = new JSONObject();
tempJson.put("longitude", reverse.getLongitude());
tempJson.put("latitude", reverse.getLatitude());
if (reverse.getLimit() != 0) {
tempJson.put("limit", reverse.getLimit());
}
if (reverse.getRadius() != 0) {
tempJson.put("radius", reverse.getRadius());
}
if (reverse.isWideSearch()) {
tempJson.put("wideSearch", reverse.isWideSearch());
}
jsonArray.put(tempJson);
tempJson = null;
}
return json.put("geolocations", jsonArray);
}
public class Reverse {
private Double longitude;
private Double latitude;
private int limit;
private int radius;
private boolean wideSearch;
public Reverse() {
}
public Reverse(Double longitude, Double latitude, int limit, int radius, boolean wideSearch) {
this.longitude = longitude;
this.latitude = latitude;
this.limit = limit;
this.radius = radius;
this.wideSearch = wideSearch;
}
public Double getLongitude() {
return longitude;
}
public Double getLatitude() {
return latitude;
}
public int getLimit() {
return limit;
}
public int getRadius() {
return radius;
}
public boolean isWideSearch() {
return wideSearch;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public void setLimit(int limit) {
this.limit = limit;
}
public void setRadius(int radius) {
this.radius = radius;
}
public void setWideSearch(boolean wideSearch) {
this.wideSearch = wideSearch;
}
}
private static Double getLongitude() {
return longitude;
}
private static Double getLatitude() {
return latitude;
}
private static int getLimit() {
return limit;
}
private static int getRadius() {
return radius;
}
public static boolean isWideSearch() {
return wideSearch;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" shutdownHook="disable">
<Appenders>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n" />
</File>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<!-- <SMTP name="Mail" subject="Error Log" to="[email protected]"
from="[email protected]" -->
<!-- smtpHost="localhost" smtpPort="25" bufferSize="50"> -->
<!-- </SMTP> -->
</Appenders>
<Loggers>
<Root level="info" />
<Root level="trace" />
<Root level="error" />
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
\ No newline at end of file
package com.postcode.io;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.net.MalformedURLException;
import org.junit.Test;
import com.postcode.io.initializers.PostcodeLookup;
/**
* @author Deepak
*
*/
public class PostCodeDetailsTest {
@Test
public void testPostCodeGenerate() throws MalformedURLException {
PostCodeDetails postCodeDetails = PostCodeDetails.generate(PostcodeLookup.postcode("bs347np").build());
assertEquals("BS34 7NP", postCodeDetails.getPostcode());
assertEquals(Integer.valueOf(1), postCodeDetails.getQuality());
assertEquals(Integer.valueOf(360605), postCodeDetails.getEastings());
assertEquals(Integer.valueOf(178655), postCodeDetails.getNorthings());
assertEquals("England", postCodeDetails.getCountry());
assertEquals("South West", postCodeDetails.getNhs_ha());
assertEquals(-2.56899282995555, postCodeDetails.getLongitude(), 1);
assertEquals(51.5054493186496, postCodeDetails.getLatitude(), 2);
assertEquals("Filton and Bradley Stoke", postCodeDetails.getParliamentary_constituency());
assertEquals("South West", postCodeDetails.getEuropean_electoral_region());
assertEquals("South Gloucestershire", postCodeDetails.getPrimary_care_trust());
assertEquals("South West", postCodeDetails.getRegion());
assertEquals("South Gloucestershire 018D", postCodeDetails.getLsoa());
assertEquals("South Gloucestershire 018", postCodeDetails.getMsoa());
assertEquals("7NP", postCodeDetails.getIncode());
assertEquals("BS34", postCodeDetails.getOutcode());
assertEquals("South Gloucestershire", postCodeDetails.getAdmin_district());
assertEquals("Filton", postCodeDetails.getParish());
assertFalse(postCodeDetails.getAdmin_county());
assertEquals("Filton", postCodeDetails.getAdmin_ward());
assertEquals("NHS South Gloucestershire", postCodeDetails.getCcg());
assertEquals("Bath and North East Somerset, North Somerset and South Gloucestershire",
postCodeDetails.getNuts());
assertEquals("E06000025", postCodeDetails.getCodes().getAdmin_district());
assertEquals("E99999999", postCodeDetails.getCodes().getAdmin_county());
assertEquals("E05002055", postCodeDetails.getCodes().getAdmin_ward());
assertEquals("E04001052", postCodeDetails.getCodes().getParish());
assertEquals("E38000155", postCodeDetails.getCodes().getCcg());
assertEquals("UKK12", postCodeDetails.getCodes().getNuts());
}
}
package com.postcode.io;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.net.MalformedURLException;
import org.junit.Test;
import com.postcode.io.initializers.PostcodeLookup;
/**
* @author Deepak
*
*/
public class PostCodeTest {
@Test
public void test() throws MalformedURLException {
PostCode postCode = PostCode.generate(new PostcodeLookup.Builder().postcode("bs347np").build());
assertEquals("BS34 7NP", postCode.getPostcode());
assertEquals(Integer.valueOf(1), postCode.getQuality());
assertEquals(Integer.valueOf(360605), postCode.getEastings());
assertEquals(Integer.valueOf(178655), postCode.getNorthings());
assertEquals("England", postCode.getCountry());
assertEquals("South West", postCode.getNhs_ha());
assertEquals(-2.56899282995555, postCode.getLongitude(), 1);
assertEquals(51.5054493186496, postCode.getLatitude(), 2);
assertEquals("Filton and Bradley Stoke", postCode.getParliamentary_constituency());
assertEquals("South West", postCode.getEuropean_electoral_region());
assertEquals("South Gloucestershire", postCode.getPrimary_care_trust());
assertEquals("South West", postCode.getRegion());
assertEquals("South Gloucestershire 018D", postCode.getLsoa());
assertEquals("South Gloucestershire 018", postCode.getMsoa());
assertEquals("7NP", postCode.getIncode());
assertEquals("BS34", postCode.getOutcode());
assertEquals("South Gloucestershire", postCode.getAdmin_district());
assertEquals("Filton", postCode.getParish());
assertFalse(postCode.getAdmin_county());
assertEquals("Filton", postCode.getAdmin_ward());
assertEquals("NHS South Gloucestershire", postCode.getCcg());
assertEquals("Bath and North East Somerset, North Somerset and South Gloucestershire", postCode.getNuts());
assertEquals("E06000025", postCode.getCodes().getAdmin_district());
assertEquals("E99999999", postCode.getCodes().getAdmin_county());
assertEquals("E05002055", postCode.getCodes().getAdmin_ward());
assertEquals("E04001052", postCode.getCodes().getParish());
assertEquals("E38000155", postCode.getCodes().getCcg());
assertEquals("UKK12", postCode.getCodes().getNuts());
}
}
package com.postcode.io.initializers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONException;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.postcode.io.initializers.ReverseGeocoding.Reverse;
import com.postcode.io.json.JsonFetcher;
/**
......@@ -18,20 +26,29 @@ import com.postcode.io.json.JsonFetcher;
*/
public class PostcodeLookupTest {
private static final Logger LOGGER = LoggerFactory.getLogger(PostcodeLookupTest.class);