Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ Test doubles are in `src/test/java/com/smartystreets/api/mocks/`:
- US Street Address (`us_street/`)
- US ZIP Code (`us_zipcode/`)
- US Reverse Geo (`us_reverse_geo/`)
- US Autocomplete (`us_autocomplete/`)
- US Autocomplete Pro (`us_autocomplete_pro/`)
- US Extract (`us_extract/`)
- US Enrichment (`us_enrichment/`)
Expand Down
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ international_street_api:
international_postal_code_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.InternationalPostalCodeExample"

us_autocomplete_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsAutocompleteExample"

us_autocomplete_pro_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsAutocompleteProExample"

Expand Down Expand Up @@ -68,6 +71,6 @@ us_street_iana_timezone_api:
us_zipcode_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsZipCodeSingleLookupExample" && mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsZipCodeMultipleLookupsExample"

examples: international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
examples: international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api

.PHONY: clean test integration-test compile publish examples international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_street_match_strategy_api us_street_iana_timezone_api us_zipcode_api
.PHONY: clean test integration-test compile publish examples international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_street_match_strategy_api us_street_iana_timezone_api us_zipcode_api
6 changes: 6 additions & 0 deletions src/main/java/com/smartystreets/api/ClientBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class ClientBuilder {
private final static String INTERNATIONAL_STREET_API_URL = "https://international-street.api.smarty.com/verify";
private final static String INTERNATIONAL_AUTOCOMPLETE_API_URL = "https://international-autocomplete.api.smarty.com/v2/lookup";
private final static String US_AUTOCOMPLETE_API_PRO_URL = "https://us-autocomplete-pro.api.smarty.com/lookup";
private final static String US_AUTOCOMPLETE_API_URL = "https://us-autocomplete.api.smarty.com/v2/lookup";
private final static String US_EXTRACT_API_URL = "https://us-extract.api.smarty.com/";
private final static String US_STREET_API_URL = "https://us-street.api.smarty.com/street-address";
private final static String US_ZIP_CODE_API_URL = "https://us-zipcode.api.smarty.com/lookup";
Expand Down Expand Up @@ -236,6 +237,11 @@ public com.smartystreets.api.us_autocomplete_pro.Client buildUsAutocompleteProAp
return new com.smartystreets.api.us_autocomplete_pro.Client(this.buildSender(), this.serializer);
}

public com.smartystreets.api.us_autocomplete.Client buildUsAutocompleteApiClient() {
this.ensureURLPrefixNotNull(US_AUTOCOMPLETE_API_URL);
return new com.smartystreets.api.us_autocomplete.Client(this.buildSender(), this.serializer);
}

public com.smartystreets.api.us_extract.Client buildUsExtractApiClient() {
this.ensureURLPrefixNotNull(US_EXTRACT_API_URL);
return new com.smartystreets.api.us_extract.Client(this.buildSender(), this.serializer);
Expand Down
92 changes: 92 additions & 0 deletions src/main/java/com/smartystreets/api/us_autocomplete/Client.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.smartystreets.api.us_autocomplete;


import com.smartystreets.api.*;
import com.smartystreets.api.exceptions.SmartyException;

import java.io.Closeable;
import java.io.IOException;
import java.util.List;

/**
* This client sends lookups to the SmartyStreets US Autocomplete API, <br>
* and attaches the results to the appropriate Lookup objects.
*/
public class Client implements Closeable {
private final Sender sender;
private final Serializer serializer;

public Client(Sender sender, Serializer serializer) {
this.sender = sender;
this.serializer = serializer;
}

public Suggestion[] send(Lookup lookup) throws SmartyException, IOException, InterruptedException {
if (lookup == null || lookup.getSearch() == null || lookup.getSearch().length() == 0)
throw new SmartyException("Send() must be passed a Lookup with the search field set.");

Request request = this.buildRequest(lookup);

Response response = this.sender.send(request);

Result result = this.serializer.deserialize(response.getPayload(), Result.class);
Suggestion[] suggestions = result.getSuggestions();
lookup.setResult(suggestions);

return suggestions;
}

private Request buildRequest(Lookup lookup) {
Request request = new Request();

request.putParameter("search", lookup.getSearch());
request.putParameter("max_results", lookup.getMaxSuggestionsStringIfSet());
request.putParameter("include_only_cities", this.buildString(lookup.getCityFilter()));
request.putParameter("include_only_states", this.buildString(lookup.getStateFilter()));
request.putParameter("include_only_zip_codes", this.buildString(lookup.getZipcodeFilter()));
request.putParameter("exclude_states", this.buildString(lookup.getExcludeStates()));
request.putParameter("prefer_cities", this.buildString(lookup.getPreferCity()));
request.putParameter("prefer_states", this.buildString(lookup.getPreferState()));
request.putParameter("prefer_zip_codes", this.buildString(lookup.getPreferZipcode()));
request.putParameter("prefer_ratio", lookup.getPreferRatioStringIfSet());
if (lookup.getGeolocateType() != null) {
request.putParameter("prefer_geolocation", lookup.getGeolocateType().getName());
}
request.putParameter("selected", lookup.getSelected());
request.putParameter("exclude", this.buildString(lookup.getExclude(), ","));
if (lookup.getSource() != null) {
request.putParameter("source", lookup.getSource().getName());
}

return request;
}

private String buildString(List<String> list) {
return buildStringFromList(list, ";");
}

private String buildString(List<String> list, String separator) {
return buildStringFromList(list, separator);
}

private String buildStringFromList(List<String> list, String separator) {
if (list.isEmpty())
return null;

String filterList = "";

for (String item : list) {
filterList += (item + separator);
}

if (filterList.endsWith(separator))
filterList = filterList.substring(0, filterList.length()-1);

return filterList;
}

@Override
public void close() throws IOException {
this.sender.close();
}
}
216 changes: 216 additions & 0 deletions src/main/java/com/smartystreets/api/us_autocomplete/Lookup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package com.smartystreets.api.us_autocomplete;

import com.smartystreets.api.GeolocateType;

import java.util.ArrayList;
import java.util.List;

/**
* In addition to holding all of the input data for this lookup, this class also<br>
* will contain the result of the lookup after it comes back from the API.
* @see "https://www.smarty.com/docs/apis/us-autocomplete-v2/reference#http-request-input-fields"
*/
public class Lookup {
final int PREFER_RATIO_DEFAULT = 100;
final int MAX_RESULTS_DEFAULT = 10;

//region [ Fields ]

private Suggestion[] result;
private String search;
private int maxResults;
private List<String> cityFilter;
private List<String> stateFilter;
private List<String> zipcodeFilter;
private List<String> excludeStates;
private List<String> preferCity;
private List<String> preferState;
private List<String> preferZipcode;
private int preferRatio;
private GeolocateType preferGeolocation;
private String selected;
private List<String> exclude;
private Source source;

//endregion

//region [ Constructors ]

/**
* If you use this constructor, don't forget to set the <b>search</b>. It is required.
*/
public Lookup() {
this.maxResults = this.MAX_RESULTS_DEFAULT;
this.preferGeolocation = GeolocateType.CITY;
this.cityFilter = new ArrayList<>();
this.stateFilter = new ArrayList<>();
this.zipcodeFilter = new ArrayList<>();
this.excludeStates = new ArrayList<>();
this.preferCity = new ArrayList<>();
this.preferState = new ArrayList<>();
this.preferZipcode = new ArrayList<>();
this.exclude = new ArrayList<>();
this.preferRatio = this.PREFER_RATIO_DEFAULT;
}

/**
* @param search The beginning of an address
*/
public Lookup(String search) {
this();
this.search = search;
}

//endregion

//region [ Getters ]

public Suggestion[] getResult() {
return this.result;
}

public Suggestion getResult(int index) {
return this.result[index];
}

public String getSearch() {
return this.search;
}

public String getSelected() { return this.selected; }

public List<String> getExclude() { return this.exclude; }

public Source getSource() { return this.source; }

public List<String> getCityFilter() {
return this.cityFilter;
}

public List<String> getStateFilter() {
return this.stateFilter;
}

public List<String> getZipcodeFilter() {
return this.zipcodeFilter;
}

public List<String> getExcludeStates() {
return this.excludeStates;
}

public List<String> getPreferCity() {
return this.preferCity;
}

public List<String> getPreferState() { return this.preferState; }

public List<String> getPreferZipcode() { return this.preferZipcode; }

public int getPreferRatio() {
return this.preferRatio;
}

String getPreferRatioStringIfSet() {
if (this.preferRatio == this.PREFER_RATIO_DEFAULT)
return null;
return Integer.toString(this.preferRatio);
}

public GeolocateType getGeolocateType() {
return preferGeolocation;
}

public int getMaxResults() {
return maxResults;
}

String getMaxSuggestionsStringIfSet() {
if (this.maxResults == this.MAX_RESULTS_DEFAULT)
return null;
return Integer.toString(this.maxResults);
}

//endregion

//region [ Setters ]

public void setResult(Suggestion[] result) {
this.result = result;
}

public void setSearch(String search) {
this.search = search;
}

public void setSelected(String selected) { this.selected = selected; }

public void setExclude(List<String> exclude) { this.exclude = exclude; }

public void addExclude(String item) { this.exclude.add(item); }

public void setSource(Source source) { this.source = source; }

public void setCityFilter(List<String> cityFilter) {
this.cityFilter = cityFilter;
}

public void setStateFilter(List<String> stateFilter) {
this.stateFilter = stateFilter;
}

public void setZipcodeFilter(List<String> zipcodeFilter) { this.zipcodeFilter = zipcodeFilter; }

public void setExcludeStates(List<String> excludeStates) { this.excludeStates = excludeStates; }

public void setPreferCity(List<String> cities) {
this.preferCity = cities;
}

public void setPreferState(List<String> states) { this.preferState = states; }

public void setPreferZipcode(List<String> zipcodes) { this.preferZipcode = zipcodes; }

/***
* Sets the percentage of suggestions that are to be from preferred cities/states.
* @param preferRatio An integer value, range [0, 100]. Default is 100.
*/
public void setPreferRatio(int preferRatio) {
this.preferRatio = preferRatio;
}

public void setGeolocateType(GeolocateType geolocateType) {
this.preferGeolocation = geolocateType;
}

/***
* Sets the maximum number of suggestions to return.
* @param maxResults A positive integer range [1, 10]. Default is 10.
* @throws IllegalArgumentException
*/
public void setMaxResults(int maxResults) throws IllegalArgumentException{
if (maxResults > 0 && maxResults <= this.MAX_RESULTS_DEFAULT) {
this.maxResults = maxResults;
} else {
throw new IllegalArgumentException("Max results must be a positive integer no larger than 10.");
}
}

public void addCityFilter(String city) {
this.cityFilter.add(city);
}

public void addStateFilter(String stateAbbreviation) {
this.stateFilter.add(stateAbbreviation);
}

public void addPreferCity(String city) {
this.preferCity.add(city);
}

public void addPreferState(String state) { this.preferState.add(state); }

public void addPreferZipcode(String zipcode) { this.preferZipcode.add(zipcode); }

//endregion
}
16 changes: 16 additions & 0 deletions src/main/java/com/smartystreets/api/us_autocomplete/Result.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.smartystreets.api.us_autocomplete;


import java.io.Serializable;

public class Result implements Serializable {
private Suggestion[] suggestions;

public Suggestion[] getSuggestions() {
return this.suggestions;
}

public Suggestion getSuggestion(int index) {
return this.suggestions[index];
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/smartystreets/api/us_autocomplete/Source.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.smartystreets.api.us_autocomplete;

public enum Source {
ALL("all"), POSTAL("postal");

private final String name;

Source(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
Loading