diff --git a/README.md b/README.md index 1523e05..246ec07 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ import com.tomaytotomato.SearchLocationService; public class Main { public static void main(String[] args) { - SearchLocationService service = new SearchLocationService(); + SearchLocationService service = SearchLocationService.builder().build(); // Find all locations named San Francisco List results = service.search("san francisco"); @@ -116,7 +116,7 @@ import com.tomaytotomato.LocationService; public class LocationServiceExample { public static void main(String[] args) { - LocationService locationService = new LocationService(); + LocationService locationService = LocationService.builder().build(); // Get all countries List countries = locationService.findAllCountries(); @@ -148,16 +148,18 @@ import com.tomaytotomato.SearchLocationService; public class LocationSearchServiceExample { public static void main(String[] args) { - SearchLocationService locationSearchService = new SearchLocationService(); + SearchLocationService searchLocationService = SearchLocationService.builder() + .withTextNormaliser(new DefaultTextNormaliser()) + .build(); // Search for Santa Clara - List results = locationSearchService.search("Santa Clara"); + List results = searchLocationService.search("Santa Clara"); // Search for Santa Clara in the USA - List resultsUnitedStates = locationSearchService.search("Santa Clara USA"); + List resultsUnitedStates = searchLocationService.search("Santa Clara USA"); // Search for Santa Clara in California (it works with ISO2 or ISO3) codes - List resultsCalifornia = locationSearchService.search("Santa Clara US CA"); + List resultsCalifornia = searchLocationService.search("Santa Clara US CA"); } } diff --git a/location4j/src/main/java/com/tomaytotomato/LocationService.java b/location4j/src/main/java/com/tomaytotomato/LocationService.java index 5d31dea..cad679c 100644 --- a/location4j/src/main/java/com/tomaytotomato/LocationService.java +++ b/location4j/src/main/java/com/tomaytotomato/LocationService.java @@ -4,11 +4,9 @@ import static java.lang.Math.sqrt; import com.tomaytotomato.loader.CountriesDataLoader; -import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; import com.tomaytotomato.model.City; import com.tomaytotomato.model.Country; import com.tomaytotomato.model.State; -import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; import com.tomaytotomato.text.normaliser.TextNormaliser; import com.tomaytotomato.usecase.FindCity; import com.tomaytotomato.usecase.FindCountry; @@ -51,27 +49,14 @@ public class LocationService implements FindCountry, FindState, FindCity { private final TextNormaliser textNormaliser; - /** - * Default constructor, creates a LocationService class with default dependencies - */ - public LocationService() { - this.textNormaliser = new DefaultTextNormaliser(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - countries = dataLoader.getCountries(); - buildDataStructures(); - } - - public LocationService(TextNormaliser textNormaliser) { + protected LocationService(TextNormaliser textNormaliser, CountriesDataLoader dataLoader) { this.textNormaliser = textNormaliser; - var dataLoader = new DefaultCountriesDataLoaderImpl(); countries = dataLoader.getCountries(); buildDataStructures(); } - public LocationService(TextNormaliser textNormaliser, CountriesDataLoader dataLoader) { - this.textNormaliser = textNormaliser; - countries = dataLoader.getCountries(); - buildDataStructures(); + public static LocationServiceBuilder builder() { + return new LocationServiceBuilder(); } private void buildDataStructures() { diff --git a/location4j/src/main/java/com/tomaytotomato/LocationServiceBuilder.java b/location4j/src/main/java/com/tomaytotomato/LocationServiceBuilder.java new file mode 100644 index 0000000..4038254 --- /dev/null +++ b/location4j/src/main/java/com/tomaytotomato/LocationServiceBuilder.java @@ -0,0 +1,29 @@ +package com.tomaytotomato; + +import com.tomaytotomato.loader.CountriesDataLoader; +import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; +import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; +import com.tomaytotomato.text.normaliser.TextNormaliser; + +public final class LocationServiceBuilder { + + private TextNormaliser textNormaliser = new DefaultTextNormaliser(); + private CountriesDataLoader countriesDataLoader = new DefaultCountriesDataLoaderImpl(); + + LocationServiceBuilder() { + } + + public LocationServiceBuilder withCountriesDataLoader(CountriesDataLoader countriesDataLoader) { + this.countriesDataLoader = countriesDataLoader; + return this; + } + + public LocationServiceBuilder withTextNormaliser(TextNormaliser textNormaliser) { + this.textNormaliser = textNormaliser; + return this; + } + + public LocationService build() { + return new LocationService(textNormaliser, countriesDataLoader); + } +} diff --git a/location4j/src/main/java/com/tomaytotomato/SearchLocationService.java b/location4j/src/main/java/com/tomaytotomato/SearchLocationService.java index 6a734f4..fb62d7d 100644 --- a/location4j/src/main/java/com/tomaytotomato/SearchLocationService.java +++ b/location4j/src/main/java/com/tomaytotomato/SearchLocationService.java @@ -1,18 +1,13 @@ package com.tomaytotomato; -import com.tomaytotomato.aliases.DefaultLocationAliases; import com.tomaytotomato.aliases.LocationAliases; import com.tomaytotomato.loader.CountriesDataLoader; -import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; -import com.tomaytotomato.mapper.DefaultLocationMapper; import com.tomaytotomato.mapper.LocationMapper; import com.tomaytotomato.model.City; import com.tomaytotomato.model.Country; import com.tomaytotomato.model.Location; import com.tomaytotomato.model.State; -import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; import com.tomaytotomato.text.normaliser.TextNormaliser; -import com.tomaytotomato.text.tokeniser.DefaultTextTokeniser; import com.tomaytotomato.text.tokeniser.TextTokeniser; import com.tomaytotomato.usecase.SearchLocation; import java.util.ArrayList; @@ -51,17 +46,7 @@ public class SearchLocationService implements SearchLocation { private final LocationMapper locationMapper; private final LocationAliases locationAliases; - public SearchLocationService() { - textTokeniser = new DefaultTextTokeniser(); - textNormaliser = new DefaultTextNormaliser(); - locationMapper = new DefaultLocationMapper(); - locationAliases = new DefaultLocationAliases(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - countries = dataLoader.getCountries(); - buildDataStructures(); - } - - public SearchLocationService(TextTokeniser textTokeniser, TextNormaliser textNormaliser, + protected SearchLocationService(TextTokeniser textTokeniser, TextNormaliser textNormaliser, LocationMapper locationMapper, CountriesDataLoader dataLoader, LocationAliases locationAliases) { this.textTokeniser = textTokeniser; @@ -72,6 +57,10 @@ public SearchLocationService(TextTokeniser textTokeniser, TextNormaliser textNor buildDataStructures(); } + public static SearchLocationServiceBuilder builder() { + return new SearchLocationServiceBuilder(); + } + private static Location buildLocationResult(Country topCountry, State topState, City topCity) { var locationBuilder = Location.builder() diff --git a/location4j/src/main/java/com/tomaytotomato/SearchLocationServiceBuilder.java b/location4j/src/main/java/com/tomaytotomato/SearchLocationServiceBuilder.java new file mode 100644 index 0000000..6bc3e6d --- /dev/null +++ b/location4j/src/main/java/com/tomaytotomato/SearchLocationServiceBuilder.java @@ -0,0 +1,58 @@ +package com.tomaytotomato; + +import com.tomaytotomato.aliases.DefaultLocationAliases; +import com.tomaytotomato.aliases.LocationAliases; +import com.tomaytotomato.loader.CountriesDataLoader; +import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; +import com.tomaytotomato.mapper.DefaultLocationMapper; +import com.tomaytotomato.mapper.LocationMapper; +import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; +import com.tomaytotomato.text.normaliser.TextNormaliser; +import com.tomaytotomato.text.tokeniser.DefaultTextTokeniser; +import com.tomaytotomato.text.tokeniser.TextTokeniser; + +/** + * Allows the customisation and creation of the {@link SearchLocationService} + */ +public final class SearchLocationServiceBuilder { + + private TextTokeniser textTokeniser = new DefaultTextTokeniser(); + private TextNormaliser textNormaliser = new DefaultTextNormaliser(); + private LocationMapper locationMapper = new DefaultLocationMapper(); + private LocationAliases locationAliases = new DefaultLocationAliases(); + private CountriesDataLoader countriesDataLoader = new DefaultCountriesDataLoaderImpl(); + + SearchLocationServiceBuilder() { + } + + public SearchLocationServiceBuilder withTextTokeniser(TextTokeniser textTokeniser) { + this.textTokeniser = textTokeniser; + return this; + } + + public SearchLocationServiceBuilder withTextNormaliser(TextNormaliser textNormaliser) { + this.textNormaliser = textNormaliser; + return this; + } + + public SearchLocationServiceBuilder withLocationMapper(LocationMapper locationMapper) { + this.locationMapper = locationMapper; + return this; + } + + public SearchLocationServiceBuilder withLocationAliases(LocationAliases locationAliases) { + this.locationAliases = locationAliases; + return this; + } + + public SearchLocationServiceBuilder withCountriesDataLoader(CountriesDataLoader countriesDataLoader) { + this.countriesDataLoader = countriesDataLoader; + return this; + } + + public SearchLocationService build() { + return new SearchLocationService(textTokeniser, textNormaliser, locationMapper, + countriesDataLoader, + locationAliases); + } +} diff --git a/location4j/src/test/java/com/tomaytotomato/usecase/FindCityTest.java b/location4j/src/test/java/com/tomaytotomato/usecase/FindCityTest.java index 0cc4365..b60dfca 100644 --- a/location4j/src/test/java/com/tomaytotomato/usecase/FindCityTest.java +++ b/location4j/src/test/java/com/tomaytotomato/usecase/FindCityTest.java @@ -5,8 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.tomaytotomato.LocationService; -import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; -import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; import java.math.BigDecimal; import jdk.jfr.Description; import org.junit.jupiter.api.DisplayName; @@ -21,9 +19,7 @@ class FindCityTest { private final FindCity locationService; public FindCityTest() { - var textNormaliser = new DefaultTextNormaliser(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - locationService = new LocationService(textNormaliser, dataLoader); + locationService = LocationService.builder().build(); } @Description("Find City by Lat/long with BigDecimal") diff --git a/location4j/src/test/java/com/tomaytotomato/usecase/FindCountriesByStateTest.java b/location4j/src/test/java/com/tomaytotomato/usecase/FindCountriesByStateTest.java index 8b539a7..c3a3606 100644 --- a/location4j/src/test/java/com/tomaytotomato/usecase/FindCountriesByStateTest.java +++ b/location4j/src/test/java/com/tomaytotomato/usecase/FindCountriesByStateTest.java @@ -4,9 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.tomaytotomato.LocationService; -import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; import com.tomaytotomato.model.Country; -import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; import jdk.jfr.Description; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,9 +18,7 @@ class FindCountriesByStateTest { private final FindCountry locationService; public FindCountriesByStateTest() { - var textNormaliser = new DefaultTextNormaliser(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - locationService = new LocationService(textNormaliser, dataLoader); + locationService = LocationService.builder().build(); } @Description("Find All Countries By State Name, when null or blank then throw exception") diff --git a/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryByISOCodeTest.java b/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryByISOCodeTest.java index 448210e..af270a2 100644 --- a/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryByISOCodeTest.java +++ b/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryByISOCodeTest.java @@ -19,9 +19,10 @@ class FindCountryByISOCodeTest { private final FindCountry locationService; public FindCountryByISOCodeTest() { - var textNormaliser = new DefaultTextNormaliser(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - locationService = new LocationService(textNormaliser, dataLoader); + locationService = LocationService.builder() + .withCountriesDataLoader(new DefaultCountriesDataLoaderImpl()) + .withTextNormaliser(new DefaultTextNormaliser()) + .build(); } @DisplayName("Get Country By ISO2 Code, when null or blank then throw exception") diff --git a/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryTest.java b/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryTest.java index 066b85f..987a958 100644 --- a/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryTest.java +++ b/location4j/src/test/java/com/tomaytotomato/usecase/FindCountryTest.java @@ -5,9 +5,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.tomaytotomato.LocationService; -import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; import com.tomaytotomato.model.Country; -import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -21,9 +19,7 @@ class FindCountryTest { private final FindCountry locationService; public FindCountryTest() { - var textNormaliser = new DefaultTextNormaliser(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - locationService = new LocationService(textNormaliser, dataLoader); + locationService = LocationService.builder().build(); } @DisplayName("Find Country By ID, when valid and exists, then return Country") diff --git a/location4j/src/test/java/com/tomaytotomato/usecase/FindStateTest.java b/location4j/src/test/java/com/tomaytotomato/usecase/FindStateTest.java index d3f9c90..c367073 100644 --- a/location4j/src/test/java/com/tomaytotomato/usecase/FindStateTest.java +++ b/location4j/src/test/java/com/tomaytotomato/usecase/FindStateTest.java @@ -5,8 +5,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.tomaytotomato.LocationService; -import com.tomaytotomato.loader.DefaultCountriesDataLoaderImpl; -import com.tomaytotomato.text.normaliser.DefaultTextNormaliser; import jdk.jfr.Description; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,9 +18,7 @@ class FindStateTest { private final FindState locationService; public FindStateTest() { - var textNormaliser = new DefaultTextNormaliser(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - locationService = new LocationService(textNormaliser, dataLoader); + locationService = LocationService.builder().build(); } @Description("Find State By ID, when null then throw exception") diff --git a/location4j/src/test/java/com/tomaytotomato/usecase/SearchLocationTest.java b/location4j/src/test/java/com/tomaytotomato/usecase/SearchLocationTest.java index 454c1f8..2badb06 100644 --- a/location4j/src/test/java/com/tomaytotomato/usecase/SearchLocationTest.java +++ b/location4j/src/test/java/com/tomaytotomato/usecase/SearchLocationTest.java @@ -23,14 +23,13 @@ class SearchLocationTest { private final SearchLocation searchLocationService; public SearchLocationTest() { - var textNormaliser = new DefaultTextNormaliser(); - var textTokeniser = new DefaultTextTokeniser(); - var locationMapper = new DefaultLocationMapper(); - var locationAliases = new DefaultLocationAliases(); - var dataLoader = new DefaultCountriesDataLoaderImpl(); - - searchLocationService = new SearchLocationService(textTokeniser, textNormaliser, locationMapper, - dataLoader, locationAliases); + searchLocationService = SearchLocationService.builder() + .withLocationAliases(new DefaultLocationAliases()) + .withLocationMapper(new DefaultLocationMapper()) + .withCountriesDataLoader(new DefaultCountriesDataLoaderImpl()) + .withTextNormaliser(new DefaultTextNormaliser()) + .withTextTokeniser(new DefaultTextTokeniser()) + .build(); } @Description("SearchLocation, when null or empty text, then throw exception") @@ -38,9 +37,7 @@ public SearchLocationTest() { void search_WhenNullOrBlank_ThenThrowException() { // When Then - assertThatThrownBy(() -> { - searchLocationService.search(null); - }).isInstanceOf(IllegalArgumentException.class) + assertThatThrownBy(() -> searchLocationService.search(null)).isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("SearchLocation Text cannot be null or empty"); }