diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0ebb039..f182dbbe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@ CHANGELOG
5.0.0
------------------
+* **BREAKING:** All model and record classes have been converted to Java records.
+ This provides a more modern, immutable data model with automatic implementations
+ of `equals()`, `hashCode()`, and `toString()`. The abstract classes
+ `AbstractRecord`, `AbstractNamedRecord`, `AbstractResponse`,
+ `AbstractCountryResponse`, `AbstractCityResponse`, and `IpBaseResponse` have
+ been removed. Record components can be accessed using the new accessor methods
+ (e.g., `city()`, `country()`, `location()`). The traditional getter methods
+ (e.g., `getCity()`, `getCountry()`, `getLocation()`) are still available but
+ have been deprecated and will be removed in version 6.0.0.
+* **BREAKING:** `RepresentedCountry` is now a separate record type instead of
+ extending `Country`. It shares the same fields as `Country` but adds a `type`
+ field.
* The deprecation notices for IP Risk database support have been removed.
IP Risk database support will continue to be maintained.
* **BREAKING:** The deprecated `WebServiceClient.Builder` methods
@@ -25,6 +37,11 @@ CHANGELOG
* **BREAKING:** Removed no longer necessary `JacksonInject` annotations for
`ip_address`, `network`, and `traits` from several classes. The
`JsonInjector` class was removed.
+* Public getter methods in non-record classes (e.g., `DatabaseReader`,
+ exception classes) have been renamed to follow the same naming convention as
+ records (e.g., `metadata()` instead of `getMetadata()`). The old getter
+ methods are still available but have been deprecated and will be removed in
+ version 6.0.0.
4.4.0 (2025-08-28)
------------------
diff --git a/pom.xml b/pom.xml
index 585ee5aa..9afd3724 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.maxmind.geoip2
geoip2
- 4.4.0
+ 5.0.0-SNAPSHOT
jar
MaxMind GeoIP2 API
GeoIP2 webservice client and database reader
@@ -36,11 +36,24 @@
goschwald@maxmind.com
+
+
+ Central Portal Snapshots
+ central-portal-snapshots
+ https://central.sonatype.com/repository/maven-snapshots/
+
+ false
+
+
+ true
+
+
+
com.maxmind.db
maxmind-db
- 3.2.0
+ 4.0.0-SNAPSHOT
com.fasterxml.jackson.core
@@ -294,10 +307,4 @@
-
-
- sonatype-nexus-staging
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
diff --git a/src/main/java/com/maxmind/geoip2/DatabaseReader.java b/src/main/java/com/maxmind/geoip2/DatabaseReader.java
index 1c220e1c..aedfeb2e 100644
--- a/src/main/java/com/maxmind/geoip2/DatabaseReader.java
+++ b/src/main/java/com/maxmind/geoip2/DatabaseReader.java
@@ -115,8 +115,8 @@ private DatabaseReader(Builder builder) throws IOException {
}
private int getDatabaseType() {
- String databaseType = this.getMetadata().getDatabaseType();
- int type = 0;
+ var databaseType = this.metadata().databaseType();
+ var type = 0;
if (databaseType.contains("GeoIP2-Anonymous-IP")) {
type |= DatabaseType.ANONYMOUS_IP.type;
}
@@ -244,26 +244,49 @@ static record LookupResult(T model, String ipAddress, Network network) {
* @param ipAddress IPv4 or IPv6 address to lookup.
* @param cls The class to deserialize to.
* @param expectedType The expected database type.
+ * @param caller The name of the public method calling this (for error messages).
* @return A {@code LookupResult} object with the data for the IP address
* @throws IOException if there is an error opening or reading from the file.
*/
private LookupResult get(InetAddress ipAddress, Class cls,
- DatabaseType expectedType)
+ DatabaseType expectedType, String caller)
throws IOException {
if ((databaseType & expectedType.type) == 0) {
- String caller = Thread.currentThread().getStackTrace()[3]
- .getMethodName();
throw new UnsupportedOperationException(
- "Invalid attempt to open a " + getMetadata().getDatabaseType()
+ "Invalid attempt to open a " + metadata().databaseType()
+ " database using the " + caller + " method");
}
- DatabaseRecord record = reader.getRecord(ipAddress, cls);
+ var record = reader.getRecord(ipAddress, cls);
- T o = record.getData();
+ var o = record.data();
- return new LookupResult<>(o, ipAddress.getHostAddress(), record.getNetwork());
+ return new LookupResult<>(o, ipAddress.getHostAddress(), record.network());
+ }
+
+ /**
+ * Generic method to get a response.
+ *
+ * @param ipAddress IPv4 or IPv6 address to lookup.
+ * @param cls The class to deserialize to.
+ * @param expectedType The expected database type.
+ * @param caller The name of the public method calling this (for error messages).
+ * @return An Optional containing the response, or empty if not found
+ * @throws IOException if there is an error opening or reading from the file.
+ */
+ private Optional getResponse(
+ InetAddress ipAddress,
+ Class cls,
+ DatabaseType expectedType,
+ String caller
+ ) throws IOException {
+ var result = this.get(ipAddress, cls, expectedType, caller);
+ var response = result.model();
+ if (response == null) {
+ return Optional.empty();
+ }
+ return Optional.of(response);
}
/**
@@ -288,79 +311,41 @@ public void close() throws IOException {
@Override
public CountryResponse country(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getCountry(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryCountry(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryCountry(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getCountry(ipAddress);
- }
-
- private Optional getCountry(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
+ var response = getResponse(
ipAddress,
CountryResponse.class,
- DatabaseType.COUNTRY
- );
- CountryResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new CountryResponse(
- response,
- result.ipAddress(),
- result.network(),
- locales
- )
+ DatabaseType.COUNTRY,
+ "country"
);
+ return response.map(r -> new CountryResponse(r, locales));
}
@Override
public CityResponse city(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getCity(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryCity(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryCity(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getCity(ipAddress);
- }
-
- private Optional getCity(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
+ var response = getResponse(
ipAddress,
CityResponse.class,
- DatabaseType.CITY
- );
- CityResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new CityResponse(
- response,
- result.ipAddress(),
- result.network(),
- locales
- )
+ DatabaseType.CITY,
+ "city"
);
+ return response.map(r -> new CityResponse(r, locales));
}
/**
@@ -374,38 +359,19 @@ private Optional getCity(
@Override
public AnonymousIpResponse anonymousIp(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getAnonymousIp(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryAnonymousIp(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryAnonymousIp(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getAnonymousIp(ipAddress);
- }
-
- private Optional getAnonymousIp(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
+ return getResponse(
ipAddress,
AnonymousIpResponse.class,
- DatabaseType.ANONYMOUS_IP
- );
- AnonymousIpResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new AnonymousIpResponse(
- response,
- result.ipAddress(),
- result.network()
- )
+ DatabaseType.ANONYMOUS_IP,
+ "anonymousIp"
);
}
@@ -420,39 +386,20 @@ private Optional getAnonymousIp(
@Override
public AnonymousPlusResponse anonymousPlus(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getAnonymousPlus(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryAnonymousPlus(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryAnonymousPlus(InetAddress ipAddress)
throws IOException,
GeoIp2Exception {
- return getAnonymousPlus(ipAddress);
- }
-
- private Optional getAnonymousPlus(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
+ return getResponse(
ipAddress,
AnonymousPlusResponse.class,
- DatabaseType.ANONYMOUS_PLUS
- );
- AnonymousPlusResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new AnonymousPlusResponse(
- response,
- result.ipAddress(),
- result.network()
- )
+ DatabaseType.ANONYMOUS_PLUS,
+ "anonymousPlus"
);
}
@@ -468,38 +415,15 @@ private Optional getAnonymousPlus(
@Override
public IpRiskResponse ipRisk(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getIpRisk(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryIpRisk(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryIpRisk(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getIpRisk(ipAddress);
- }
-
- private Optional getIpRisk(InetAddress ipAddress) throws IOException,
- GeoIp2Exception {
- LookupResult result = this.get(
- ipAddress,
- IpRiskResponse.class,
- DatabaseType.IP_RISK
- );
- IpRiskResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new IpRiskResponse(
- response,
- result.ipAddress(),
- result.network()
- )
- );
+ return getResponse(ipAddress, IpRiskResponse.class, DatabaseType.IP_RISK, "ipRisk");
}
/**
@@ -513,38 +437,15 @@ private Optional getIpRisk(InetAddress ipAddress) throws IOExcep
@Override
public AsnResponse asn(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getAsn(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryAsn(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryAsn(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getAsn(ipAddress);
- }
-
- private Optional getAsn(InetAddress ipAddress)
- throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
- ipAddress,
- AsnResponse.class,
- DatabaseType.ASN
- );
- AsnResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new AsnResponse(
- response,
- result.ipAddress(),
- result.network()
- )
- );
+ return getResponse(ipAddress, AsnResponse.class, DatabaseType.ASN, "asn");
}
/**
@@ -558,38 +459,19 @@ private Optional getAsn(InetAddress ipAddress)
@Override
public ConnectionTypeResponse connectionType(InetAddress ipAddress)
throws IOException, GeoIp2Exception {
- Optional r = getConnectionType(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryConnectionType(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryConnectionType(InetAddress ipAddress)
throws IOException, GeoIp2Exception {
- return getConnectionType(ipAddress);
- }
-
- private Optional getConnectionType(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
+ return getResponse(
ipAddress,
ConnectionTypeResponse.class,
- DatabaseType.CONNECTION_TYPE
- );
- ConnectionTypeResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new ConnectionTypeResponse(
- response,
- result.ipAddress(),
- result.network()
- )
+ DatabaseType.CONNECTION_TYPE,
+ "connectionType"
);
}
@@ -604,39 +486,15 @@ private Optional getConnectionType(
@Override
public DomainResponse domain(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getDomain(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryDomain(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryDomain(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getDomain(ipAddress);
- }
-
- private Optional getDomain(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
- ipAddress,
- DomainResponse.class,
- DatabaseType.DOMAIN
- );
- DomainResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new DomainResponse(
- response,
- result.ipAddress(),
- result.network()
- )
- );
+ return getResponse(ipAddress, DomainResponse.class, DatabaseType.DOMAIN, "domain");
}
/**
@@ -650,40 +508,21 @@ private Optional getDomain(
@Override
public EnterpriseResponse enterprise(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getEnterprise(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryEnterprise(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryEnterprise(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getEnterprise(ipAddress);
- }
-
- private Optional getEnterprise(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
+ var response = getResponse(
ipAddress,
EnterpriseResponse.class,
- DatabaseType.ENTERPRISE
- );
- EnterpriseResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new EnterpriseResponse(
- response,
- result.ipAddress(),
- result.network(),
- locales
- )
+ DatabaseType.ENTERPRISE,
+ "enterprise"
);
+ return response.map(r -> new EnterpriseResponse(r, locales));
}
/**
@@ -697,45 +536,30 @@ private Optional getEnterprise(
@Override
public IspResponse isp(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- Optional r = getIsp(ipAddress);
- if (r.isEmpty()) {
- throw new AddressNotFoundException("The address "
- + ipAddress.getHostAddress() + " is not in the database.");
- }
- return r.get();
+ return tryIsp(ipAddress).orElseThrow(() ->
+ new AddressNotFoundException("The address "
+ + ipAddress.getHostAddress() + " is not in the database."));
}
@Override
public Optional tryIsp(InetAddress ipAddress) throws IOException,
GeoIp2Exception {
- return getIsp(ipAddress);
+ return getResponse(ipAddress, IspResponse.class, DatabaseType.ISP, "isp");
}
- private Optional getIsp(
- InetAddress ipAddress
- ) throws IOException, GeoIp2Exception {
- LookupResult result = this.get(
- ipAddress,
- IspResponse.class,
- DatabaseType.ISP
- );
- IspResponse response = result.model();
- if (response == null) {
- return Optional.empty();
- }
- return Optional.of(
- new IspResponse(
- response,
- result.ipAddress(),
- result.network()
- )
- );
+ /**
+ * @return the metadata for the open MaxMind DB file.
+ */
+ public Metadata metadata() {
+ return this.reader.getMetadata();
}
/**
* @return the metadata for the open MaxMind DB file.
+ * @deprecated Use {@link #metadata()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public Metadata getMetadata() {
- return this.reader.getMetadata();
+ return metadata();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/InetAddressDeserializer.java b/src/main/java/com/maxmind/geoip2/InetAddressDeserializer.java
new file mode 100644
index 00000000..8c61609b
--- /dev/null
+++ b/src/main/java/com/maxmind/geoip2/InetAddressDeserializer.java
@@ -0,0 +1,34 @@
+package com.maxmind.geoip2;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Deserializes a string to an InetAddress.
+ */
+public class InetAddressDeserializer extends StdDeserializer {
+ /**
+ * Constructs an instance of {@code InetAddressDeserializer}.
+ */
+ public InetAddressDeserializer() {
+ super(InetAddress.class);
+ }
+
+ @Override
+ public InetAddress deserialize(JsonParser p, DeserializationContext ctxt)
+ throws IOException {
+ var value = p.getValueAsString();
+ if (value == null || value.isEmpty()) {
+ return null;
+ }
+ try {
+ return InetAddress.getByName(value);
+ } catch (UnknownHostException e) {
+ throw new IOException("Invalid IP address: " + value, e);
+ }
+ }
+}
diff --git a/src/main/java/com/maxmind/geoip2/InetAddressModule.java b/src/main/java/com/maxmind/geoip2/InetAddressModule.java
new file mode 100644
index 00000000..6b989a4a
--- /dev/null
+++ b/src/main/java/com/maxmind/geoip2/InetAddressModule.java
@@ -0,0 +1,18 @@
+package com.maxmind.geoip2;
+
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import java.net.InetAddress;
+
+/**
+ * Jackson module for InetAddress serialization and deserialization.
+ */
+public class InetAddressModule extends SimpleModule {
+ /**
+ * Constructs an instance of {@code InetAddressModule}.
+ */
+ public InetAddressModule() {
+ super("InetAddressModule");
+ addSerializer(InetAddress.class, new InetAddressSerializer());
+ addDeserializer(InetAddress.class, new InetAddressDeserializer());
+ }
+}
diff --git a/src/main/java/com/maxmind/geoip2/InetAddressSerializer.java b/src/main/java/com/maxmind/geoip2/InetAddressSerializer.java
new file mode 100644
index 00000000..38319841
--- /dev/null
+++ b/src/main/java/com/maxmind/geoip2/InetAddressSerializer.java
@@ -0,0 +1,29 @@
+package com.maxmind.geoip2;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+import java.io.IOException;
+import java.net.InetAddress;
+
+/**
+ * Serializes InetAddress to its host address string representation.
+ */
+public class InetAddressSerializer extends StdSerializer {
+ /**
+ * Constructs an instance of {@code InetAddressSerializer}.
+ */
+ public InetAddressSerializer() {
+ super(InetAddress.class);
+ }
+
+ @Override
+ public void serialize(InetAddress value, JsonGenerator gen, SerializerProvider provider)
+ throws IOException {
+ if (value == null) {
+ gen.writeNull();
+ } else {
+ gen.writeString(value.getHostAddress());
+ }
+ }
+}
diff --git a/src/main/java/com/maxmind/geoip2/record/AbstractRecord.java b/src/main/java/com/maxmind/geoip2/JsonSerializable.java
similarity index 61%
rename from src/main/java/com/maxmind/geoip2/record/AbstractRecord.java
rename to src/main/java/com/maxmind/geoip2/JsonSerializable.java
index 631d795d..190553cd 100644
--- a/src/main/java/com/maxmind/geoip2/record/AbstractRecord.java
+++ b/src/main/java/com/maxmind/geoip2/JsonSerializable.java
@@ -1,23 +1,27 @@
-package com.maxmind.geoip2.record;
+package com.maxmind.geoip2;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
/**
- * Abstract class for GeoIP2.
+ * Interface for classes that can be serialized to JSON.
+ * Provides default implementation for toJson() method.
*/
-public abstract class AbstractRecord {
+public interface JsonSerializable {
/**
* @return JSON representation of this object. The structure is the same as
* the JSON provided by the GeoIP2 web service.
* @throws IOException if there is an error serializing the object to JSON.
*/
- public String toJson() throws IOException {
+ default String toJson() throws IOException {
JsonMapper mapper = JsonMapper.builder()
.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
+ .addModule(new JavaTimeModule())
+ .addModule(new InetAddressModule())
.serializationInclusion(JsonInclude.Include.NON_NULL)
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
.build();
@@ -25,14 +29,4 @@ public String toJson() throws IOException {
return mapper.writeValueAsString(this);
}
- @Override
- public String toString() {
- // This exception should never happen. If it does happen, we did
- // something wrong.
- try {
- return getClass().getName() + " [ " + toJson() + " ]";
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
}
diff --git a/src/main/java/com/maxmind/geoip2/NamedRecord.java b/src/main/java/com/maxmind/geoip2/NamedRecord.java
new file mode 100644
index 00000000..b2c30ebd
--- /dev/null
+++ b/src/main/java/com/maxmind/geoip2/NamedRecord.java
@@ -0,0 +1,47 @@
+package com.maxmind.geoip2;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface for record classes that have localized names and GeoName IDs.
+ * Provides a default implementation for the name() method that returns the name
+ * in the first available locale.
+ */
+public interface NamedRecord extends JsonSerializable {
+
+ /**
+ * @return The GeoName ID for this location.
+ */
+ @JsonProperty("geoname_id")
+ Long geonameId();
+
+ /**
+ * @return A {@link Map} from locale codes to the name in that locale.
+ */
+ @JsonProperty("names")
+ Map names();
+
+ /**
+ * @return The list of locales to use for name lookups.
+ */
+ @JsonIgnore
+ List locales();
+
+ /**
+ * @return The name based on the locales list. Returns the name in the first
+ * locale for which a name is available. If no name is available in any of the
+ * specified locales, returns null.
+ */
+ @JsonIgnore
+ default String name() {
+ for (var lang : locales()) {
+ if (names().containsKey(lang)) {
+ return names().get(lang);
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/maxmind/geoip2/NetworkDeserializer.java b/src/main/java/com/maxmind/geoip2/NetworkDeserializer.java
index 7932b6f2..670ddc52 100644
--- a/src/main/java/com/maxmind/geoip2/NetworkDeserializer.java
+++ b/src/main/java/com/maxmind/geoip2/NetworkDeserializer.java
@@ -33,7 +33,7 @@ public NetworkDeserializer(Class> vc) {
public Network deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException {
- final String cidr = jsonparser.getValueAsString();
+ final var cidr = jsonparser.getValueAsString();
if (cidr == null || cidr.isBlank()) {
return null;
}
@@ -41,13 +41,13 @@ public Network deserialize(JsonParser jsonparser, DeserializationContext context
}
private static Network parseCidr(String cidr) throws IOException {
- final String[] parts = cidr.split("/", 2);
+ final var parts = cidr.split("/", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Invalid CIDR format: " + cidr);
}
- final String addrPart = parts[0];
- final String prefixPart = parts[1];
+ final var addrPart = parts[0];
+ final var prefixPart = parts[1];
final InetAddress address;
try {
@@ -56,15 +56,9 @@ private static Network parseCidr(String cidr) throws IOException {
throw new IOException("Unknown host in CIDR: " + cidr, e);
}
- final int prefixLength;
- try {
- prefixLength = Integer.parseInt(prefixPart);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException(
- "Invalid prefix length in CIDR: " + cidr, e);
- }
+ final var prefixLength = parsePrefixLength(prefixPart, cidr);
- final int maxPrefix = (address.getAddress().length == 4) ? 32 : 128;
+ final var maxPrefix = (address.getAddress().length == 4) ? 32 : 128;
if (prefixLength < 0 || prefixLength > maxPrefix) {
throw new IllegalArgumentException(
"Prefix length out of range (0-" + maxPrefix + ") for CIDR: " + cidr);
@@ -72,4 +66,13 @@ private static Network parseCidr(String cidr) throws IOException {
return new Network(address, prefixLength);
}
+
+ private static int parsePrefixLength(String prefixPart, String cidr) {
+ try {
+ return Integer.parseInt(prefixPart);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ "Invalid prefix length in CIDR: " + cidr, e);
+ }
+ }
}
diff --git a/src/main/java/com/maxmind/geoip2/WebServiceClient.java b/src/main/java/com/maxmind/geoip2/WebServiceClient.java
index 2e653201..c48169a9 100644
--- a/src/main/java/com/maxmind/geoip2/WebServiceClient.java
+++ b/src/main/java/com/maxmind/geoip2/WebServiceClient.java
@@ -356,9 +356,9 @@ public InsightsResponse insights(InetAddress ipAddress) throws IOException,
private T responseFor(String path, InetAddress ipAddress, Class cls)
throws IOException, GeoIp2Exception {
- URI uri = createUri(path, ipAddress);
+ var uri = createUri(path, ipAddress);
- HttpRequest request = HttpRequest.newBuilder()
+ var request = HttpRequest.newBuilder()
.uri(uri)
.timeout(this.requestTimeout)
.header("Accept", "application/json")
@@ -366,24 +366,23 @@ private T responseFor(String path, InetAddress ipAddress, Class cls)
.header("User-Agent", this.userAgent)
.GET()
.build();
- HttpResponse response = null;
try {
- response = this.httpClient
+ var response = this.httpClient
.send(request, HttpResponse.BodyHandlers.ofInputStream());
- return handleResponse(response, cls);
- } catch (InterruptedException e) {
- throw new GeoIp2Exception("Interrupted sending request", e);
- } finally {
- if (response != null) {
+ try {
+ return handleResponse(response, cls);
+ } finally {
response.body().close();
}
+ } catch (InterruptedException e) {
+ throw new GeoIp2Exception("Interrupted sending request", e);
}
}
private T handleResponse(HttpResponse response, Class cls)
throws GeoIp2Exception, IOException {
- int status = response.statusCode();
- URI uri = response.uri();
+ var status = response.statusCode();
+ var uri = response.uri();
if (status >= 400 && status < 500) {
this.handle4xxStatus(response);
@@ -397,7 +396,7 @@ private T handleResponse(HttpResponse response, Class cls)
+ status + ") for " + uri, status, uri);
}
- InjectableValues inject = new InjectableValues.Std()
+ var inject = new InjectableValues.Std()
.addValue("locales", locales);
try {
@@ -410,20 +409,17 @@ private T handleResponse(HttpResponse response, Class cls)
private void handle4xxStatus(HttpResponse response)
throws GeoIp2Exception, IOException {
- int status = response.statusCode();
- URI uri = response.uri();
-
- String body;
- try (InputStream bodyStream = response.body()) {
- body = new String(bodyStream.readAllBytes(), StandardCharsets.UTF_8);
- if (body.equals("")) {
- throw new HttpException("Received a " + status + " error for "
- + uri + " with no body", status, uri);
- }
+ var status = response.statusCode();
+ var uri = response.uri();
+
+ final var body = readBody(response);
+ if (body.isEmpty()) {
+ throw new HttpException("Received a " + status + " error for "
+ + uri + " with no body", status, uri);
}
try {
- Map content = mapper.readValue(body,
+ var content = mapper.readValue(body,
new TypeReference>() {
});
handleErrorWithJsonBody(content, body, status, uri);
@@ -439,8 +435,8 @@ private void handle4xxStatus(HttpResponse response)
private static void handleErrorWithJsonBody(Map content,
String body, int status, URI uri)
throws GeoIp2Exception, HttpException {
- String error = content.get("error");
- String code = content.get("code");
+ var error = content.get("error");
+ var code = content.get("code");
if (error == null || code == null) {
throw new HttpException(
@@ -449,29 +445,23 @@ private static void handleErrorWithJsonBody(Map content,
}
switch (code) {
- case "IP_ADDRESS_NOT_FOUND":
- case "IP_ADDRESS_RESERVED":
+ case "IP_ADDRESS_NOT_FOUND", "IP_ADDRESS_RESERVED" ->
throw new AddressNotFoundException(error);
- case "ACCOUNT_ID_REQUIRED":
- case "ACCOUNT_ID_UNKNOWN":
- case "AUTHORIZATION_INVALID":
- case "LICENSE_KEY_REQUIRED":
- case "USER_ID_REQUIRED":
- case "USER_ID_UNKNOWN":
+ case "ACCOUNT_ID_REQUIRED", "ACCOUNT_ID_UNKNOWN", "AUTHORIZATION_INVALID",
+ "LICENSE_KEY_REQUIRED", "USER_ID_REQUIRED", "USER_ID_UNKNOWN" ->
throw new AuthenticationException(error);
- case "INSUFFICIENT_FUNDS":
- case "OUT_OF_QUERIES":
+ case "INSUFFICIENT_FUNDS", "OUT_OF_QUERIES" ->
throw new OutOfQueriesException(error);
- case "PERMISSION_REQUIRED":
+ case "PERMISSION_REQUIRED" ->
throw new PermissionRequiredException(error);
- default:
+ default ->
// These should be fairly rare
throw new InvalidRequestException(error, code, uri);
}
}
private URI createUri(String service, InetAddress ipAddress) throws GeoIp2Exception {
- String path = "/geoip/v2.1/" + service + "/"
+ var path = "/geoip/v2.1/" + service + "/"
+ (ipAddress == null ? "me" : ipAddress.getHostAddress());
try {
return new URI(
@@ -489,7 +479,7 @@ private URI createUri(String service, InetAddress ipAddress) throws GeoIp2Except
}
private void exhaustBody(HttpResponse response) throws HttpException {
- try (InputStream body = response.body()) {
+ try (var body = response.body()) {
// Make sure we read the stream until the end so that
// the connection can be reused.
while (body.read() != -1) {
@@ -500,6 +490,11 @@ private void exhaustBody(HttpResponse response) throws HttpExceptio
}
}
+ private static String readBody(HttpResponse response) throws IOException {
+ try (var bodyStream = response.body()) {
+ return new String(bodyStream.readAllBytes(), StandardCharsets.UTF_8);
+ }
+ }
@Override
public String toString() {
diff --git a/src/main/java/com/maxmind/geoip2/exception/GeoIp2Exception.java b/src/main/java/com/maxmind/geoip2/exception/GeoIp2Exception.java
index 967cd034..24afd18d 100644
--- a/src/main/java/com/maxmind/geoip2/exception/GeoIp2Exception.java
+++ b/src/main/java/com/maxmind/geoip2/exception/GeoIp2Exception.java
@@ -4,7 +4,12 @@
* This class represents a generic GeoIP2 error. All other exceptions thrown by
* the GeoIP2 API subclass this exception
*/
-public class GeoIp2Exception extends Exception {
+public sealed class GeoIp2Exception extends Exception
+ permits AddressNotFoundException,
+ AuthenticationException,
+ InvalidRequestException,
+ OutOfQueriesException,
+ PermissionRequiredException {
/**
diff --git a/src/main/java/com/maxmind/geoip2/exception/HttpException.java b/src/main/java/com/maxmind/geoip2/exception/HttpException.java
index a73d8f9d..7cf497b6 100644
--- a/src/main/java/com/maxmind/geoip2/exception/HttpException.java
+++ b/src/main/java/com/maxmind/geoip2/exception/HttpException.java
@@ -39,16 +39,34 @@ public HttpException(String message, int httpStatus, URI uri,
/**
* @return the HTTP status of the query that caused the exception.
*/
- public int getHttpStatus() {
+ public int httpStatus() {
return this.httpStatus;
}
+ /**
+ * @return the HTTP status of the query that caused the exception.
+ * @deprecated Use {@link #httpStatus()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public int getHttpStatus() {
+ return httpStatus();
+ }
+
/**
* @return the URI queried.
*/
- public URI getUri() {
+ public URI uri() {
return this.uri;
}
+ /**
+ * @return the URI queried.
+ * @deprecated Use {@link #uri()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public URI getUri() {
+ return uri();
+ }
+
}
diff --git a/src/main/java/com/maxmind/geoip2/exception/InvalidRequestException.java b/src/main/java/com/maxmind/geoip2/exception/InvalidRequestException.java
index 58c845d7..1acd388e 100644
--- a/src/main/java/com/maxmind/geoip2/exception/InvalidRequestException.java
+++ b/src/main/java/com/maxmind/geoip2/exception/InvalidRequestException.java
@@ -39,15 +39,33 @@ public InvalidRequestException(String message, String code, int httpStatus,
/**
* @return The error code returned by the MaxMind web service.
*/
- public String getCode() {
+ public String code() {
return this.code;
}
+ /**
+ * @return The error code returned by the MaxMind web service.
+ * @deprecated Use {@link #code()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public String getCode() {
+ return code();
+ }
+
/**
* @return the URI queried.
*/
- public URI getUri() {
+ public URI uri() {
return this.uri;
}
+ /**
+ * @return the URI queried.
+ * @deprecated Use {@link #uri()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public URI getUri() {
+ return uri();
+ }
+
}
diff --git a/src/main/java/com/maxmind/geoip2/model/AbstractCityResponse.java b/src/main/java/com/maxmind/geoip2/model/AbstractCityResponse.java
deleted file mode 100644
index 6cc4bec2..00000000
--- a/src/main/java/com/maxmind/geoip2/model/AbstractCityResponse.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.maxmind.geoip2.model;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.maxmind.db.Network;
-import com.maxmind.geoip2.record.City;
-import com.maxmind.geoip2.record.Continent;
-import com.maxmind.geoip2.record.Country;
-import com.maxmind.geoip2.record.Location;
-import com.maxmind.geoip2.record.MaxMind;
-import com.maxmind.geoip2.record.Postal;
-import com.maxmind.geoip2.record.RepresentedCountry;
-import com.maxmind.geoip2.record.Subdivision;
-import com.maxmind.geoip2.record.Traits;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Abstract class for models that contain City data.
- */
-public abstract class AbstractCityResponse extends AbstractCountryResponse {
-
- private final City city;
- private final Location location;
- private final Postal postal;
- private final List subdivisions;
-
- AbstractCityResponse(
- City city,
- Continent continent,
- Country country,
- Location location,
- MaxMind maxmind,
- Postal postal,
- Country registeredCountry,
- RepresentedCountry representedCountry,
- List subdivisions,
- Traits traits
- ) {
- super(continent, country, maxmind, registeredCountry, representedCountry, traits);
- this.city = city != null ? city : new City();
- this.location = location != null ? location : new Location();
- this.postal = postal != null ? postal : new Postal();
- this.subdivisions = subdivisions != null ? subdivisions : new ArrayList<>();
- }
-
- AbstractCityResponse(
- AbstractCityResponse response,
- String ipAddress,
- Network network,
- List locales
- ) {
- super(response, ipAddress, network, locales);
- // The response fields will be non-null because of the above
- // constructor used during deserializing.
- this.city = new City(response.getCity(), locales);
- this.location = response.getLocation();
- this.postal = response.getPostal();
- this.subdivisions = mapSubdivisions(response.getSubdivisions(), locales);
- }
-
- private static ArrayList mapSubdivisions(
- List subdivisions,
- List locales
- ) {
- ArrayList subdivisions2 = new ArrayList<>(subdivisions.size());
- for (Subdivision subdivision : subdivisions) {
- subdivisions2.add(new Subdivision(subdivision, locales));
- }
- return subdivisions2;
- }
-
- /**
- * @return City record for the requested IP address.
- */
- public City getCity() {
- return this.city;
- }
-
- /**
- * @return Location record for the requested IP address.
- */
- public Location getLocation() {
- return this.location;
- }
-
- /**
- * @return the postal
- */
- public Postal getPostal() {
- return this.postal;
- }
-
- /**
- * @return An {@link List} of {@link Subdivision} objects representing the
- * country subdivisions for the requested IP address. The number and
- * type of subdivisions varies by country, but a subdivision is
- * typically a state, province, county, etc. Subdivisions are
- * ordered from most general (largest) to most specific (smallest).
- * If the response did not contain any subdivisions, this method
- * returns an empty array.
- */
- public List getSubdivisions() {
- return new ArrayList<>(this.subdivisions);
- }
-
- /**
- * @return An object representing the most specific subdivision returned. If
- * the response did not contain any subdivisions, this method
- * returns an empty {@link Subdivision} object.
- */
- @JsonIgnore
- public Subdivision getMostSpecificSubdivision() {
- if (this.subdivisions.isEmpty()) {
- return new Subdivision();
- }
- return this.subdivisions.get(this.subdivisions.size() - 1);
- }
-
- /**
- * @return An object representing the least specific subdivision returned. If
- * the response did not contain any subdivisions, this method
- * returns an empty {@link Subdivision} object.
- */
- @JsonIgnore
- public Subdivision getLeastSpecificSubdivision() {
- if (this.subdivisions.isEmpty()) {
- return new Subdivision();
- }
- return this.subdivisions.get(0);
- }
-}
diff --git a/src/main/java/com/maxmind/geoip2/model/AbstractCountryResponse.java b/src/main/java/com/maxmind/geoip2/model/AbstractCountryResponse.java
deleted file mode 100644
index 615e1765..00000000
--- a/src/main/java/com/maxmind/geoip2/model/AbstractCountryResponse.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.maxmind.geoip2.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.Network;
-import com.maxmind.geoip2.record.Continent;
-import com.maxmind.geoip2.record.Country;
-import com.maxmind.geoip2.record.MaxMind;
-import com.maxmind.geoip2.record.RepresentedCountry;
-import com.maxmind.geoip2.record.Traits;
-import java.util.List;
-
-/**
-* Abstract class for models that contain Country data.
- */
-public abstract class AbstractCountryResponse extends AbstractResponse {
-
- private final Continent continent;
- private final Country country;
- private final Country registeredCountry;
- private final MaxMind maxmind;
- private final RepresentedCountry representedCountry;
- private final Traits traits;
-
- AbstractCountryResponse(
- Continent continent,
- Country country,
- MaxMind maxmind,
- Country registeredCountry,
- RepresentedCountry representedCountry,
- Traits traits
- ) {
- this.continent = continent != null ? continent : new Continent();
- this.country = country != null ? country : new Country();
- this.registeredCountry = registeredCountry != null ? registeredCountry : new Country();
- this.maxmind = maxmind != null ? maxmind : new MaxMind();
- this.representedCountry =
- representedCountry != null ? representedCountry : new RepresentedCountry();
- this.traits = traits != null ? traits : new Traits();
- }
-
- AbstractCountryResponse(
- AbstractCountryResponse response,
- String ipAddress,
- Network network,
- List locales
- ) {
- // The response fields will be non-null because of the above
- // constructor used during deserializing.
- this.continent = new Continent(response.getContinent(), locales);
- this.country = new Country(response.getCountry(), locales);
- this.maxmind = response.getMaxMind();
- this.registeredCountry = new Country(response.getRegisteredCountry(), locales);
- this.representedCountry = new RepresentedCountry(response.getRepresentedCountry(), locales);
- this.traits = new Traits(response.getTraits(), ipAddress, network);
- }
-
- /**
- * @return MaxMind record containing data related to your account.
- */
- @JsonProperty("maxmind")
- public MaxMind getMaxMind() {
- return this.maxmind;
- }
-
- /**
- * @return Registered country record for the requested IP address. This
- * record represents the country where the ISP has registered a
- * given IP block and may differ from the user's country.
- */
- @JsonProperty("registered_country")
- public Country getRegisteredCountry() {
- return this.registeredCountry;
- }
-
- /**
- * @return Continent record for the requested IP address.
- */
- public Continent getContinent() {
- return this.continent;
- }
-
- /**
- * @return Country record for the requested IP address. This object
- * represents the country where MaxMind believes the end user is
- * located.
- */
- public Country getCountry() {
- return this.country;
- }
-
- /**
- * @return Represented country record for the requested IP address. The
- * represented country is used for things like military bases. It is
- * only present when the represented country differs from the
- * country.
- */
- @JsonProperty("represented_country")
- public RepresentedCountry getRepresentedCountry() {
- return this.representedCountry;
- }
-
- /**
- * @return Record for the traits of the requested IP address.
- */
- public Traits getTraits() {
- return this.traits;
- }
-}
diff --git a/src/main/java/com/maxmind/geoip2/model/AbstractResponse.java b/src/main/java/com/maxmind/geoip2/model/AbstractResponse.java
deleted file mode 100644
index 6c742f1b..00000000
--- a/src/main/java/com/maxmind/geoip2/model/AbstractResponse.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.maxmind.geoip2.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.databind.MapperFeature;
-import com.fasterxml.jackson.databind.json.JsonMapper;
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import java.io.IOException;
-
-/**
- * Abstract class for GeoIP2 models.
- */
-public abstract class AbstractResponse {
-
- /**
- * @return JSON representation of this object. The structure is the same as
- * the JSON provided by the GeoIP2 web service.
- * @throws IOException if there is an error serializing the object to JSON.
- */
- public String toJson() throws IOException {
- JsonMapper mapper = JsonMapper.builder()
- .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
- .addModule(new JavaTimeModule())
- .serializationInclusion(Include.NON_NULL)
- .serializationInclusion(Include.NON_EMPTY)
- .build();
-
- return mapper.writeValueAsString(this);
- }
-
- @Override
- public String toString() {
- // This exception should never happen. If it does happen, we did
- // something wrong.
- try {
- return getClass().getName() + " [ " + toJson() + " ]";
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/main/java/com/maxmind/geoip2/model/AnonymousIpResponse.java b/src/main/java/com/maxmind/geoip2/model/AnonymousIpResponse.java
index 923023b9..c8a22226 100644
--- a/src/main/java/com/maxmind/geoip2/model/AnonymousIpResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/AnonymousIpResponse.java
@@ -1,102 +1,89 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
/**
* This class provides the GeoIP2 Anonymous IP model.
+ *
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param isAnonymous Whether the IP address belongs to any sort of anonymous network.
+ * @param isAnonymousVpn Whether the IP address is registered to an anonymous VPN provider. If a
+ * VPN provider does not register subnets under names associated with them,
+ * we will likely only flag their IP ranges using isHostingProvider.
+ * @param isHostingProvider Whether the IP address belongs to a hosting or VPN provider (see
+ * description of isAnonymousVpn).
+ * @param isPublicProxy Whether the IP address belongs to a public proxy.
+ * @param isResidentialProxy Whether the IP address is on a suspected anonymizing network and
+ * belongs to a residential ISP.
+ * @param isTorExitNode Whether the IP address is a Tor exit node.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
*/
-public class AnonymousIpResponse extends IpBaseResponse {
+public record AnonymousIpResponse(
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
- /**
- * Constructs an instance of {@code AnonymousIpResponse} with the specified values.
- *
- * @param ipAddress the IP address being checked
- * @param isAnonymous whether the IP address belongs to any sort of anonymous network
- * @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
- * @param isHostingProvider whether the IP address belongs to a hosting provider
- * @param isPublicProxy whether the IP address belongs to a public proxy system
- * @param isResidentialProxy whether the IP address belongs to a residential proxy system
- * @param isTorExitNode whether the IP address is a Tor exit node
- * @param network the network associated with the record
- */
- public AnonymousIpResponse(
- @JsonProperty("ip_address") String ipAddress,
- @JsonProperty("is_anonymous") boolean isAnonymous,
- @JsonProperty("is_anonymous_vpn") boolean isAnonymousVpn,
- @JsonProperty("is_hosting_provider") boolean isHostingProvider,
- @JsonProperty("is_public_proxy") boolean isPublicProxy,
- @JsonProperty("is_residential_proxy") boolean isResidentialProxy,
- @JsonProperty("is_tor_exit_node") boolean isTorExitNode,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) Network network
- ) {
- super(ipAddress, isAnonymous, isAnonymousVpn, isHostingProvider, isPublicProxy,
- isResidentialProxy, isTorExitNode, network);
- }
+ @JsonProperty("is_anonymous")
+ @MaxMindDbParameter(name = "is_anonymous", useDefault = true)
+ boolean isAnonymous,
+
+ @JsonProperty("is_anonymous_vpn")
+ @MaxMindDbParameter(name = "is_anonymous_vpn", useDefault = true)
+ boolean isAnonymousVpn,
+
+ @JsonProperty("is_hosting_provider")
+ @MaxMindDbParameter(name = "is_hosting_provider", useDefault = true)
+ boolean isHostingProvider,
+
+ @JsonProperty("is_public_proxy")
+ @MaxMindDbParameter(name = "is_public_proxy", useDefault = true)
+ boolean isPublicProxy,
+
+ @JsonProperty("is_residential_proxy")
+ @MaxMindDbParameter(name = "is_residential_proxy", useDefault = true)
+ boolean isResidentialProxy,
+
+ @JsonProperty("is_tor_exit_node")
+ @MaxMindDbParameter(name = "is_tor_exit_node", useDefault = true)
+ boolean isTorExitNode,
+
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @MaxMindDbNetwork
+ Network network
+) implements JsonSerializable {
/**
- * Constructs an instance of {@code AnonymousIpResponse} with the specified values.
- *
- * @param ipAddress the IP address being checked
- * @param isAnonymous whether the IP address belongs to any sort of anonymous network
- * @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
- * @param isHostingProvider whether the IP address belongs to a hosting provider
- * @param isPublicProxy whether the IP address belongs to a public proxy system
- * @param isResidentialProxy whether the IP address belongs to a residential proxy system
- * @param isTorExitNode whether the IP address is a Tor exit node
- * @param network the network associated with the record
+ * @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
*/
- @MaxMindDbConstructor
- public AnonymousIpResponse(
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @MaxMindDbParameter(name = "is_anonymous") Boolean isAnonymous,
- @MaxMindDbParameter(name = "is_anonymous_vpn") Boolean isAnonymousVpn,
- @MaxMindDbParameter(name = "is_hosting_provider") Boolean isHostingProvider,
- @MaxMindDbParameter(name = "is_public_proxy") Boolean isPublicProxy,
- @MaxMindDbParameter(name = "is_residential_proxy") Boolean isResidentialProxy,
- @MaxMindDbParameter(name = "is_tor_exit_node") Boolean isTorExitNode,
- @MaxMindDbParameter(name = "network") Network network
- ) {
- this(
- ipAddress,
- isAnonymous != null ? isAnonymous : false,
- isAnonymousVpn != null ? isAnonymousVpn : false,
- isHostingProvider != null ? isHostingProvider : false,
- isPublicProxy != null ? isPublicProxy : false,
- isResidentialProxy != null ? isResidentialProxy : false,
- isTorExitNode != null ? isTorExitNode : false,
- network
- );
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("ip_address")
+ public String getIpAddress() {
+ return ipAddress().getHostAddress();
}
/**
- * Constructs an instance of {@code AnonymousIpResponse} from the values in the passed
- * response and the specified IP address and network.
- *
- * @param response the response to copy
- * @param ipAddress the IP address being checked
- * @param network the network associated with the record
+ * @return The network associated with the record. In particular, this is
+ * the largest network where all the fields besides IP address have the
+ * same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
*/
- public AnonymousIpResponse(
- AnonymousIpResponse response,
- String ipAddress,
- Network network
- ) {
- this(
- ipAddress,
- response.isAnonymous(),
- response.isAnonymousVpn(),
- response.isHostingProvider(),
- response.isPublicProxy(),
- response.isResidentialProxy(),
- response.isTorExitNode(),
- network
- );
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty
+ @JsonSerialize(using = ToStringSerializer.class)
+ public Network getNetwork() {
+ return network();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/AnonymousPlusResponse.java b/src/main/java/com/maxmind/geoip2/model/AnonymousPlusResponse.java
index 169d1e2a..22ac498b 100644
--- a/src/main/java/com/maxmind/geoip2/model/AnonymousPlusResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/AnonymousPlusResponse.java
@@ -1,63 +1,93 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.maxmind.db.MaxMindDbConstructor;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
import java.time.LocalDate;
/**
* This class provides the GeoIP Anonymous Plus model.
+ *
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param isAnonymous Whether the IP address belongs to any sort of anonymous network.
+ * @param isAnonymousVpn Whether the IP address is registered to an anonymous VPN provider. If a
+ * VPN provider does not register subnets under names associated with them,
+ * we will likely only flag their IP ranges using isHostingProvider.
+ * @param isHostingProvider Whether the IP address belongs to a hosting or VPN provider (see
+ * description of isAnonymousVpn).
+ * @param isPublicProxy Whether the IP address belongs to a public proxy.
+ * @param isResidentialProxy Whether the IP address is on a suspected anonymizing network and
+ * belongs to a residential ISP.
+ * @param isTorExitNode Whether the IP address is a Tor exit node.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
+ * @param anonymizerConfidence A score ranging from 1 to 99 that is our percent confidence that
+ * the network is currently part of an actively used VPN service.
+ * @param networkLastSeen The last day that the network was sighted in our analysis of anonymized
+ * networks.
+ * @param providerName The name of the VPN provider (e.g., NordVPN, SurfShark, etc.) associated
+ * with the network.
*/
-public class AnonymousPlusResponse extends AnonymousIpResponse {
- private final Integer anonymizerConfidence;
- private final LocalDate networkLastSeen;
- private final String providerName;
+public record AnonymousPlusResponse(
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
- /**
- * Constructs an instance of {@code AnonymousPlusResponse} with the specified values.
- *
- * @param anonymizerConfidence confidence that the network is a VPN.
- * @param ipAddress the IP address being checked
- * @param isAnonymous whether the IP address belongs to any sort of anonymous network
- * @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
- * @param isHostingProvider whether the IP address belongs to a hosting provider
- * @param isPublicProxy whether the IP address belongs to a public proxy system
- * @param isResidentialProxy whether the IP address belongs to a residential proxy system
- * @param isTorExitNode whether the IP address is a Tor exit node
- * @param network the network associated with the record
- * @param networkLastSeen the last sighting of the network.
- * @param providerName the name of the VPN provider.
- */
- public AnonymousPlusResponse(
- @JsonProperty("anonymizer_confidence") Integer anonymizerConfidence,
- @JsonProperty("ip_address") String ipAddress,
- @JsonProperty("is_anonymous") Boolean isAnonymous,
- @JsonProperty("is_anonymous_vpn") Boolean isAnonymousVpn,
- @JsonProperty("is_hosting_provider") Boolean isHostingProvider,
- @JsonProperty("is_public_proxy") Boolean isPublicProxy,
- @JsonProperty("is_residential_proxy") Boolean isResidentialProxy,
- @JsonProperty("is_tor_exit_node") Boolean isTorExitNode,
- @JsonDeserialize(using = NetworkDeserializer.class)
- @JsonProperty("network") Network network,
- @JsonProperty("network_last_seen") LocalDate networkLastSeen,
- @JsonProperty("provider_name") String providerName
- ) {
- super(ipAddress, isAnonymous, isAnonymousVpn, isHostingProvider, isPublicProxy,
- isResidentialProxy, isTorExitNode, network);
+ @JsonProperty("is_anonymous")
+ @MaxMindDbParameter(name = "is_anonymous", useDefault = true)
+ boolean isAnonymous,
- this.anonymizerConfidence = anonymizerConfidence;
- this.networkLastSeen = networkLastSeen;
- this.providerName = providerName;
- }
+ @JsonProperty("is_anonymous_vpn")
+ @MaxMindDbParameter(name = "is_anonymous_vpn", useDefault = true)
+ boolean isAnonymousVpn,
+
+ @JsonProperty("is_hosting_provider")
+ @MaxMindDbParameter(name = "is_hosting_provider", useDefault = true)
+ boolean isHostingProvider,
+
+ @JsonProperty("is_public_proxy")
+ @MaxMindDbParameter(name = "is_public_proxy", useDefault = true)
+ boolean isPublicProxy,
+
+ @JsonProperty("is_residential_proxy")
+ @MaxMindDbParameter(name = "is_residential_proxy", useDefault = true)
+ boolean isResidentialProxy,
+
+ @JsonProperty("is_tor_exit_node")
+ @MaxMindDbParameter(name = "is_tor_exit_node", useDefault = true)
+ boolean isTorExitNode,
+
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @MaxMindDbNetwork
+ Network network,
+
+ @JsonProperty("anonymizer_confidence")
+ @MaxMindDbParameter(name = "anonymizer_confidence")
+ Integer anonymizerConfidence,
+
+ @JsonProperty("network_last_seen")
+ @MaxMindDbParameter(name = "network_last_seen")
+ LocalDate networkLastSeen,
+
+ @JsonProperty("provider_name")
+ @MaxMindDbParameter(name = "provider_name")
+ String providerName
+) implements JsonSerializable {
/**
- * Constructs an instance of {@code AnonymousPlusResponse} with the specified values.
+ * Constructs an instance of {@code AnonymousPlusResponse} with date parsing
+ * from MaxMind database.
*
- * @param anonymizerConfidence confidence that the network is a VPN.
* @param ipAddress the IP address being checked
* @param isAnonymous whether the IP address belongs to any sort of anonymous network
* @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
@@ -66,80 +96,98 @@ public AnonymousPlusResponse(
* @param isResidentialProxy whether the IP address belongs to a residential proxy system
* @param isTorExitNode whether the IP address is a Tor exit node
* @param network the network associated with the record
+ * @param anonymizerConfidence confidence that the network is a VPN.
* @param networkLastSeen the last sighting of the network.
* @param providerName the name of the VPN provider.
*/
@MaxMindDbConstructor
public AnonymousPlusResponse(
+ @MaxMindDbIpAddress InetAddress ipAddress,
+ @MaxMindDbParameter(name = "is_anonymous", useDefault = true)
+ boolean isAnonymous,
+ @MaxMindDbParameter(name = "is_anonymous_vpn", useDefault = true)
+ boolean isAnonymousVpn,
+ @MaxMindDbParameter(name = "is_hosting_provider", useDefault = true)
+ boolean isHostingProvider,
+ @MaxMindDbParameter(name = "is_public_proxy", useDefault = true)
+ boolean isPublicProxy,
+ @MaxMindDbParameter(name = "is_residential_proxy", useDefault = true)
+ boolean isResidentialProxy,
+ @MaxMindDbParameter(name = "is_tor_exit_node", useDefault = true)
+ boolean isTorExitNode,
+ @MaxMindDbNetwork Network network,
@MaxMindDbParameter(name = "anonymizer_confidence") Integer anonymizerConfidence,
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @MaxMindDbParameter(name = "is_anonymous") Boolean isAnonymous,
- @MaxMindDbParameter(name = "is_anonymous_vpn") Boolean isAnonymousVpn,
- @MaxMindDbParameter(name = "is_hosting_provider") Boolean isHostingProvider,
- @MaxMindDbParameter(name = "is_public_proxy") Boolean isPublicProxy,
- @MaxMindDbParameter(name = "is_residential_proxy") Boolean isResidentialProxy,
- @MaxMindDbParameter(name = "is_tor_exit_node") Boolean isTorExitNode,
- @MaxMindDbParameter(name = "network") Network network,
@MaxMindDbParameter(name = "network_last_seen") String networkLastSeen,
@MaxMindDbParameter(name = "provider_name") String providerName
) {
- this(anonymizerConfidence, ipAddress, isAnonymous, isAnonymousVpn,
- isHostingProvider, isPublicProxy, isResidentialProxy, isTorExitNode, network,
+ this(
+ ipAddress,
+ isAnonymous,
+ isAnonymousVpn,
+ isHostingProvider,
+ isPublicProxy,
+ isResidentialProxy,
+ isTorExitNode,
+ network,
+ anonymizerConfidence,
networkLastSeen != null ? LocalDate.parse(networkLastSeen) : null,
- providerName);
+ providerName
+ );
}
/**
- * Constructs an instance of {@code AnonymousPlusResponse} from the values in the
- * response and the specified IP address and network.
- *
- * @param response the response to copy
- * @param ipAddress the IP address being checked
- * @param network the network associated with the record
+ * @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
*/
- public AnonymousPlusResponse(
- AnonymousPlusResponse response,
- String ipAddress,
- Network network
- ) {
- this(
- response.getAnonymizerConfidence(),
- ipAddress,
- response.isAnonymous(),
- response.isAnonymousVpn(),
- response.isHostingProvider(),
- response.isPublicProxy(),
- response.isResidentialProxy(),
- response.isTorExitNode(),
- network,
- response.getNetworkLastSeen(),
- response.getProviderName()
- );
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("ip_address")
+ public String getIpAddress() {
+ return ipAddress().getHostAddress();
+ }
+
+ /**
+ * @return The network associated with the record. In particular, this is
+ * the largest network where all the fields besides IP address have the
+ * same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty
+ @JsonSerialize(using = ToStringSerializer.class)
+ public Network getNetwork() {
+ return network();
}
/**
* @return A score ranging from 1 to 99 that is our percent confidence that the network is
* currently part of an actively used VPN service.
+ * @deprecated Use {@link #anonymizerConfidence()} instead. This method will be removed
+ * in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
public Integer getAnonymizerConfidence() {
- return anonymizerConfidence;
+ return anonymizerConfidence();
}
/**
* @return The last day that the network was sighted in our analysis of anonymized networks.
+ * @deprecated Use {@link #networkLastSeen()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
public LocalDate getNetworkLastSeen() {
- return networkLastSeen;
+ return networkLastSeen();
}
/**
* @return The name of the VPN provider (e.g., NordVPN, SurfShark, etc.) associated with the
* network.
+ * @deprecated Use {@link #providerName()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
public String getProviderName() {
- return providerName;
+ return providerName();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/AsnResponse.java b/src/main/java/com/maxmind/geoip2/model/AsnResponse.java
index a33717d2..0dea5f03 100644
--- a/src/main/java/com/maxmind/geoip2/model/AsnResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/AsnResponse.java
@@ -1,107 +1,89 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
/**
* This class provides the GeoLite2 ASN model.
+ *
+ * @param autonomousSystemNumber The autonomous system number associated with the IP address.
+ * @param autonomousSystemOrganization The organization associated with the registered autonomous
+ * system number for the IP address.
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
*/
-public class AsnResponse extends AbstractResponse {
+public record AsnResponse(
+ @JsonProperty("autonomous_system_number")
+ @MaxMindDbParameter(name = "autonomous_system_number")
+ Long autonomousSystemNumber,
- private final Long autonomousSystemNumber;
- private final String autonomousSystemOrganization;
- private final String ipAddress;
- private final Network network;
+ @JsonProperty("autonomous_system_organization")
+ @MaxMindDbParameter(name = "autonomous_system_organization")
+ String autonomousSystemOrganization,
- /**
- * Constructs an instance of {@code AsnResponse} with the specified values for all fields.
- *
- * @param autonomousSystemNumber the autonomous system number associated with the IP
- * address
- * @param autonomousSystemOrganization the organization associated with the registered
- * autonomous system number for the IP address
- * @param ipAddress the IP address that the data in the model is for
- * @param network the network associated with the record
- */
- @MaxMindDbConstructor
- public AsnResponse(
- @JsonProperty("autonomous_system_number")
- @MaxMindDbParameter(name = "autonomous_system_number") Long autonomousSystemNumber,
- @JsonProperty("autonomous_system_organization")
- @MaxMindDbParameter(name = "autonomous_system_organization")
- String autonomousSystemOrganization,
- @JsonProperty("ip_address")
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) @MaxMindDbParameter(name = "network")
- Network network
- ) {
- this.autonomousSystemNumber = autonomousSystemNumber;
- this.autonomousSystemOrganization = autonomousSystemOrganization;
- this.ipAddress = ipAddress;
- this.network = network;
- }
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
- /**
- * Constructs an instance of {@code AsnResponse} with only the specified values set.
- *
- * @param response The {@code AsnResponse} object to copy.
- * @param ipAddress The IP address that the data in the model is for.
- * @param network The network associated with the record.
- */
- public AsnResponse(
- AsnResponse response,
- String ipAddress,
- Network network
- ) {
- this(
- response.getAutonomousSystemNumber(),
- response.getAutonomousSystemOrganization(),
- ipAddress,
- network
- );
- }
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @MaxMindDbNetwork
+ Network network
+) implements JsonSerializable {
/**
* @return The autonomous system number associated with the IP address.
+ * @deprecated Use {@link #autonomousSystemNumber()} instead. This method will be removed
+ * in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("autonomous_system_number")
public Long getAutonomousSystemNumber() {
- return this.autonomousSystemNumber;
+ return autonomousSystemNumber();
}
/**
* @return The organization associated with the registered autonomous system
* number for the IP address
+ * @deprecated Use {@link #autonomousSystemOrganization()} instead. This method will be
+ * removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("autonomous_system_organization")
public String getAutonomousSystemOrganization() {
- return this.autonomousSystemOrganization;
+ return autonomousSystemOrganization();
}
/**
* @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("ip_address")
public String getIpAddress() {
- return this.ipAddress;
+ return ipAddress().getHostAddress();
}
/**
* @return The network associated with the record. In particular, this is
* the largest network where all the fields besides IP address have the
* same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
@JsonSerialize(using = ToStringSerializer.class)
public Network getNetwork() {
- return this.network;
+ return network();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/CityResponse.java b/src/main/java/com/maxmind/geoip2/model/CityResponse.java
index a9e64f65..f6f35254 100644
--- a/src/main/java/com/maxmind/geoip2/model/CityResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/CityResponse.java
@@ -1,10 +1,9 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
-import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Continent;
import com.maxmind.geoip2.record.Country;
@@ -21,59 +20,278 @@
* This class provides a model for the data returned by the City Plus web
* service and the City database.
*
+ * @param city City record for the requested IP address.
+ * @param continent Continent record for the requested IP address.
+ * @param country Country record for the requested IP address. This object represents the country
+ * where MaxMind believes the end user is located.
+ * @param location Location record for the requested IP address.
+ * @param maxmind MaxMind record containing data related to your account.
+ * @param postal Postal record for the requested IP address.
+ * @param registeredCountry Registered country record for the requested IP address. This record
+ * represents the country where the ISP has registered a given IP block
+ * and may differ from the user's country.
+ * @param representedCountry Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the country.
+ * @param subdivisions An {@link List} of {@link Subdivision} objects representing the country
+ * subdivisions for the requested IP address. The number and type of
+ * subdivisions varies by country, but a subdivision is typically a state,
+ * province, county, etc. Subdivisions are ordered from most general (largest)
+ * to most specific (smallest). If the response did not contain any
+ * subdivisions, this is an empty list.
+ * @param traits Record for the traits of the requested IP address.
* @see GeoIP2 Web
* Services
*/
-public final class CityResponse extends AbstractCityResponse {
+public record CityResponse(
+ @JsonProperty("city")
+ @MaxMindDbParameter(name = "city")
+ City city,
+
+ @JsonProperty("continent")
+ @MaxMindDbParameter(name = "continent")
+ Continent continent,
+
+ @JsonProperty("country")
+ @MaxMindDbParameter(name = "country")
+ Country country,
+
+ @JsonProperty("location")
+ @MaxMindDbParameter(name = "location")
+ Location location,
+
+ @JsonProperty("maxmind")
+ @MaxMindDbParameter(name = "maxmind")
+ MaxMind maxmind,
+
+ @JsonProperty("postal")
+ @MaxMindDbParameter(name = "postal")
+ Postal postal,
+
+ @JsonProperty("registered_country")
+ @MaxMindDbParameter(name = "registered_country")
+ Country registeredCountry,
+
+ @JsonProperty("represented_country")
+ @MaxMindDbParameter(name = "represented_country")
+ RepresentedCountry representedCountry,
+
+ @JsonProperty("subdivisions")
+ @MaxMindDbParameter(name = "subdivisions")
+ List subdivisions,
+
+ @JsonProperty("traits")
+ @MaxMindDbParameter(name = "traits")
+ Traits traits
+) implements JsonSerializable {
+
/**
- * Constructs an instance of {@code CityResponse} with the specified parameters.
- *
- * @param city city
- * @param continent continent
- * @param country country
- * @param location location
- * @param maxmind maxmind record for the response
- * @param postal postal
- * @param registeredCountry registered country
- * @param representedCountry represented country
- * @param subdivisions subdivisions
- * @param traits traits
- */
- @MaxMindDbConstructor
- public CityResponse(
- @JsonProperty("city") @MaxMindDbParameter(name = "city") City city,
- @JsonProperty("continent") @MaxMindDbParameter(name = "continent") Continent continent,
- @JsonProperty("country") @MaxMindDbParameter(name = "country") Country country,
- @JsonProperty("location") @MaxMindDbParameter(name = "location") Location location,
- @JsonProperty("maxmind") @MaxMindDbParameter(name = "maxmind") MaxMind maxmind,
- @JsonProperty("postal") @MaxMindDbParameter(name = "postal") Postal postal,
- @JsonProperty("registered_country") @MaxMindDbParameter(name = "registered_country")
- Country registeredCountry,
- @JsonProperty("represented_country") @MaxMindDbParameter(name = "represented_country")
- RepresentedCountry representedCountry,
- @JsonProperty("subdivisions") @MaxMindDbParameter(name = "subdivisions")
- ArrayList subdivisions,
- @JsonProperty("traits") @MaxMindDbParameter(name = "traits")
- Traits traits
- ) {
- super(city, continent, country, location, maxmind, postal, registeredCountry,
- representedCountry, subdivisions, traits);
+ * Compact canonical constructor that sets defaults for null values.
+ */
+ public CityResponse {
+ city = city != null ? city : new City();
+ continent = continent != null ? continent : new Continent();
+ country = country != null ? country : new Country();
+ location = location != null ? location : new Location();
+ maxmind = maxmind != null ? maxmind : new MaxMind();
+ postal = postal != null ? postal : new Postal();
+ registeredCountry = registeredCountry != null ? registeredCountry : new Country();
+ representedCountry = representedCountry != null
+ ? representedCountry : new RepresentedCountry();
+ subdivisions = subdivisions != null ? List.copyOf(subdivisions) : List.of();
+ traits = traits != null ? traits : new Traits();
}
/**
* Constructs an instance of {@code CityResponse} with the specified parameters.
*
* @param response the response
- * @param ipAddress the IP address that the data in the model is for.
- * @param network the network associated with the record.
* @param locales the locales
*/
public CityResponse(
CityResponse response,
- String ipAddress,
- Network network,
List locales
) {
- super(response, ipAddress, network, locales);
+ this(
+ new City(response.city(), locales),
+ new Continent(response.continent(), locales),
+ new Country(response.country(), locales),
+ response.location(),
+ response.maxmind(),
+ response.postal(),
+ new Country(response.registeredCountry(), locales),
+ new RepresentedCountry(response.representedCountry(), locales),
+ mapSubdivisions(response.subdivisions(), locales),
+ response.traits()
+ );
+ }
+
+ private static ArrayList mapSubdivisions(
+ List subdivisions,
+ List locales
+ ) {
+ var subdivisions2 = new ArrayList(subdivisions.size());
+ for (var subdivision : subdivisions) {
+ subdivisions2.add(new Subdivision(subdivision, locales));
+ }
+ return subdivisions2;
+ }
+
+ /**
+ * @return City record for the requested IP address.
+ * @deprecated Use {@link #city()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public City getCity() {
+ return city();
+ }
+
+ /**
+ * @return Continent record for the requested IP address.
+ * @deprecated Use {@link #continent()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Continent getContinent() {
+ return continent();
+ }
+
+ /**
+ * @return Country record for the requested IP address. This object
+ * represents the country where MaxMind believes the end user is
+ * located.
+ * @deprecated Use {@link #country()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Country getCountry() {
+ return country();
+ }
+
+ /**
+ * @return Location record for the requested IP address.
+ * @deprecated Use {@link #location()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Location getLocation() {
+ return location();
+ }
+
+ /**
+ * @return MaxMind record containing data related to your account.
+ * @deprecated Use {@link #maxmind()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("maxmind")
+ public MaxMind getMaxMind() {
+ return maxmind();
+ }
+
+ /**
+ * @return the postal
+ * @deprecated Use {@link #postal()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Postal getPostal() {
+ return postal();
+ }
+
+ /**
+ * @return Registered country record for the requested IP address. This
+ * record represents the country where the ISP has registered a
+ * given IP block and may differ from the user's country.
+ * @deprecated Use {@link #registeredCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("registered_country")
+ public Country getRegisteredCountry() {
+ return registeredCountry();
+ }
+
+ /**
+ * @return Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the
+ * country.
+ * @deprecated Use {@link #representedCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("represented_country")
+ public RepresentedCountry getRepresentedCountry() {
+ return representedCountry();
+ }
+
+ /**
+ * @return An {@link List} of {@link Subdivision} objects representing the
+ * country subdivisions for the requested IP address. The number and
+ * type of subdivisions varies by country, but a subdivision is
+ * typically a state, province, county, etc. Subdivisions are
+ * ordered from most general (largest) to most specific (smallest).
+ * If the response did not contain any subdivisions, this method
+ * returns an empty array.
+ * @deprecated Use {@link #subdivisions()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public List getSubdivisions() {
+ return new ArrayList<>(subdivisions());
+ }
+
+ /**
+ * @return Record for the traits of the requested IP address.
+ * @deprecated Use {@link #traits()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Traits getTraits() {
+ return traits();
+ }
+
+ /**
+ * @return An object representing the most specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ */
+ @JsonIgnore
+ public Subdivision mostSpecificSubdivision() {
+ if (subdivisions().isEmpty()) {
+ return new Subdivision();
+ }
+ return subdivisions().get(subdivisions().size() - 1);
+ }
+
+ /**
+ * @return An object representing the most specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ * @deprecated Use {@link #mostSpecificSubdivision()} instead. This method will be removed
+ * in 6.0.0.
+ */
+ @JsonIgnore
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Subdivision getMostSpecificSubdivision() {
+ return mostSpecificSubdivision();
+ }
+
+ /**
+ * @return An object representing the least specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ */
+ @JsonIgnore
+ public Subdivision leastSpecificSubdivision() {
+ if (subdivisions().isEmpty()) {
+ return new Subdivision();
+ }
+ return subdivisions().get(0);
+ }
+
+ /**
+ * @return An object representing the least specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ * @deprecated Use {@link #leastSpecificSubdivision()} instead. This method will be removed
+ * in 6.0.0.
+ */
+ @JsonIgnore
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Subdivision getLeastSpecificSubdivision() {
+ return leastSpecificSubdivision();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/ConnectionTypeResponse.java b/src/main/java/com/maxmind/geoip2/model/ConnectionTypeResponse.java
index 06c956f7..40b492c9 100644
--- a/src/main/java/com/maxmind/geoip2/model/ConnectionTypeResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/ConnectionTypeResponse.java
@@ -1,21 +1,42 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.maxmind.db.MaxMindDbCreator;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
/**
* This class provides the GeoIP2 Connection-Type model.
+ *
+ * @param connectionType The connection type of the IP address.
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
*/
-public class ConnectionTypeResponse extends AbstractResponse {
+public record ConnectionTypeResponse(
+ @JsonProperty("connection_type")
+ @MaxMindDbParameter(name = "connection_type")
+ ConnectionType connectionType,
+
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
+
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @MaxMindDbNetwork
+ Network network
+) implements JsonSerializable {
/**
* The enumerated values that connection-type may take.
@@ -50,6 +71,7 @@ public String toString() {
* @param s The string to create the instance from.
*/
@JsonCreator
+ @MaxMindDbCreator
public static ConnectionType fromString(String s) {
if (s == null) {
return null;
@@ -66,91 +88,36 @@ public static ConnectionType fromString(String s) {
}
}
- private final ConnectionType connectionType;
- private final String ipAddress;
- private final Network network;
-
- /**
- * Constructs an instance of {@code ConnectionTypeResponse}.
- *
- * @param connectionType The connection type of the IP address.
- * @param ipAddress The IP address that the data in the model is for.
- * @param network The network associated with the record.
- */
- public ConnectionTypeResponse(
- @JsonProperty("connection_type") ConnectionType connectionType,
- @JsonProperty("ip_address") String ipAddress,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) Network network
- ) {
- this.connectionType = connectionType;
- this.ipAddress = ipAddress;
- this.network = network;
- }
-
- /**
- * Constructs an instance of {@code ConnectionTypeResponse}.
- *
- * @param connectionType The connection type of the IP address.
- * @param ipAddress The IP address that the data in the model is for.
- * @param network The network associated with the record.
- */
- @MaxMindDbConstructor
- public ConnectionTypeResponse(
- @MaxMindDbParameter(name = "connection_type") String connectionType,
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @MaxMindDbParameter(name = "network") Network network
- ) {
- this(
- ConnectionType.fromString(connectionType),
- ipAddress,
- network
- );
- }
-
- /**
- * Constructs an instance of {@code ConnectionTypeResponse}.
- *
- * @param response The {@code ConnectionTypeResponse} object to copy.
- * @param ipAddress The IP address that the data in the model is for.
- * @param network The network associated with the record.
- */
- public ConnectionTypeResponse(
- ConnectionTypeResponse response,
- String ipAddress,
- Network network
- ) {
- this(
- response.getConnectionType(),
- ipAddress,
- network
- );
- }
-
/**
* @return The connection type of the IP address.
+ * @deprecated Use {@link #connectionType()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("connection_type")
public ConnectionType getConnectionType() {
- return this.connectionType;
+ return connectionType();
}
/**
* @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("ip_address")
public String getIpAddress() {
- return this.ipAddress;
+ return ipAddress().getHostAddress();
}
/**
* @return The network associated with the record. In particular, this is
* the largest network where all the fields besides IP address have the
* same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
@JsonSerialize(using = ToStringSerializer.class)
public Network getNetwork() {
- return this.network;
+ return network();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/CountryResponse.java b/src/main/java/com/maxmind/geoip2/model/CountryResponse.java
index 364c9bc6..23c3c3f2 100644
--- a/src/main/java/com/maxmind/geoip2/model/CountryResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/CountryResponse.java
@@ -1,10 +1,8 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
-import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.record.Continent;
import com.maxmind.geoip2.record.Country;
import com.maxmind.geoip2.record.MaxMind;
@@ -16,50 +14,140 @@
* This class provides a model for the data returned by the Country web service
* and the Country database.
*
+ * @param continent Continent record for the requested IP address.
+ * @param country Country record for the requested IP address. This object represents the country
+ * where MaxMind believes the end user is located.
+ * @param maxmind MaxMind record containing data related to your account.
+ * @param registeredCountry Registered country record for the requested IP address. This record
+ * represents the country where the ISP has registered a given IP block
+ * and may differ from the user's country.
+ * @param representedCountry Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the country.
+ * @param traits Record for the traits of the requested IP address.
* @see GeoIP2 Web
* Services
*/
-public final class CountryResponse extends AbstractCountryResponse {
+public record CountryResponse(
+ @JsonProperty("continent")
+ @MaxMindDbParameter(name = "continent")
+ Continent continent,
+
+ @JsonProperty("country")
+ @MaxMindDbParameter(name = "country")
+ Country country,
+
+ @JsonProperty("maxmind")
+ @MaxMindDbParameter(name = "maxmind")
+ MaxMind maxmind,
+
+ @JsonProperty("registered_country")
+ @MaxMindDbParameter(name = "registered_country")
+ Country registeredCountry,
+
+ @JsonProperty("represented_country")
+ @MaxMindDbParameter(name = "represented_country")
+ RepresentedCountry representedCountry,
+
+ @JsonProperty("traits")
+ @MaxMindDbParameter(name = "traits")
+ Traits traits
+) implements JsonSerializable {
/**
- * Constructs an instance of {@code CountryResponse} with the specified parameters.
- *
- * @param continent the continent
- * @param country the country
- * @param maxmind the MaxMind record
- * @param registeredCountry the registered country
- * @param representedCountry the represented country
- * @param traits the traits
+ * Compact canonical constructor that sets defaults for null values.
*/
- @MaxMindDbConstructor
- public CountryResponse(
- @JsonProperty("continent") @MaxMindDbParameter(name = "continent") Continent continent,
- @JsonProperty("country") @MaxMindDbParameter(name = "country") Country country,
- @JsonProperty("maxmind") @MaxMindDbParameter(name = "maxmind") MaxMind maxmind,
- @JsonProperty("registered_country") @MaxMindDbParameter(name = "registered_country")
- Country registeredCountry,
- @JsonProperty("represented_country") @MaxMindDbParameter(name = "represented_country")
- RepresentedCountry representedCountry,
- @JsonProperty("traits") @MaxMindDbParameter(name = "traits")
- Traits traits
- ) {
- super(continent, country, maxmind, registeredCountry, representedCountry, traits);
+ public CountryResponse {
+ continent = continent != null ? continent : new Continent();
+ country = country != null ? country : new Country();
+ maxmind = maxmind != null ? maxmind : new MaxMind();
+ registeredCountry = registeredCountry != null ? registeredCountry : new Country();
+ representedCountry = representedCountry != null
+ ? representedCountry : new RepresentedCountry();
+ traits = traits != null ? traits : new Traits();
}
/**
* Constructs an instance of {@code CountryResponse} with the specified parameters.
*
* @param response the response
- * @param ipAddress the IP address that the data in the model is for.
- * @param network the network associated with the record.
* @param locales the locales
*/
public CountryResponse(
CountryResponse response,
- String ipAddress,
- Network network,
List locales
) {
- super(response, ipAddress, network, locales);
+ this(
+ new Continent(response.continent(), locales),
+ new Country(response.country(), locales),
+ response.maxmind(),
+ new Country(response.registeredCountry(), locales),
+ new RepresentedCountry(response.representedCountry(), locales),
+ response.traits()
+ );
+ }
+
+ /**
+ * @return MaxMind record containing data related to your account.
+ * @deprecated Use {@link #maxmind()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("maxmind")
+ public MaxMind getMaxMind() {
+ return maxmind();
+ }
+
+ /**
+ * @return Registered country record for the requested IP address. This
+ * record represents the country where the ISP has registered a
+ * given IP block and may differ from the user's country.
+ * @deprecated Use {@link #registeredCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("registered_country")
+ public Country getRegisteredCountry() {
+ return registeredCountry();
+ }
+
+ /**
+ * @return Continent record for the requested IP address.
+ * @deprecated Use {@link #continent()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Continent getContinent() {
+ return continent();
+ }
+
+ /**
+ * @return Country record for the requested IP address. This object
+ * represents the country where MaxMind believes the end user is
+ * located.
+ * @deprecated Use {@link #country()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Country getCountry() {
+ return country();
+ }
+
+ /**
+ * @return Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the
+ * country.
+ * @deprecated Use {@link #representedCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("represented_country")
+ public RepresentedCountry getRepresentedCountry() {
+ return representedCountry();
+ }
+
+ /**
+ * @return Record for the traits of the requested IP address.
+ * @deprecated Use {@link #traits()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Traits getTraits() {
+ return traits();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/DomainResponse.java b/src/main/java/com/maxmind/geoip2/model/DomainResponse.java
index 81b12987..347f255c 100644
--- a/src/main/java/com/maxmind/geoip2/model/DomainResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/DomainResponse.java
@@ -1,85 +1,72 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
/**
* This class provides the GeoIP2 Domain model.
+ *
+ * @param domain The second level domain associated with the IP address. This will be something
+ * like "example.com" or "example.co.uk", not "foo.example.com".
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
*/
-public class DomainResponse extends AbstractResponse {
+public record DomainResponse(
+ @JsonProperty("domain")
+ @MaxMindDbParameter(name = "domain")
+ String domain,
- private final String domain;
- private final String ipAddress;
- private final Network network;
-
- /**
- * Constructs an instance of {@code DomainResponse}.
- *
- * @param domain the second level domain associated with the IP address
- * @param ipAddress the IP address that the data in the model is for
- * @param network the network associated with the record
- */
- @MaxMindDbConstructor
- public DomainResponse(
- @JsonProperty("domain") @MaxMindDbParameter(name = "domain") String domain,
- @JsonProperty("ip_address")
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) @MaxMindDbParameter(name = "network")
- Network network
- ) {
- this.domain = domain;
- this.ipAddress = ipAddress;
- this.network = network;
- }
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
- /**
- * Constructs an instance of {@code DomainResponse} with only required parameters.
- *
- * @param response the response
- * @param ipAddress the IP address that the data in the model is for.
- * @param network the network associated with the record.
- */
- public DomainResponse(
- DomainResponse response,
- String ipAddress,
- Network network
- ) {
- this(response.getDomain(), ipAddress, network);
- }
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @MaxMindDbNetwork
+ Network network
+) implements JsonSerializable {
/**
* @return The second level domain associated with the IP address. This
* will be something like "example.com" or "example.co.uk", not
* "foo.example.com".
+ * @deprecated Use {@link #domain()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getDomain() {
- return this.domain;
+ return domain();
}
/**
* @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("ip_address")
public String getIpAddress() {
- return this.ipAddress;
+ return ipAddress().getHostAddress();
}
/**
* @return The network associated with the record. In particular, this is
* the largest network where all the fields besides IP address have the
* same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
@JsonSerialize(using = ToStringSerializer.class)
public Network getNetwork() {
- return this.network;
+ return network();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/EnterpriseResponse.java b/src/main/java/com/maxmind/geoip2/model/EnterpriseResponse.java
index 700c025f..5cc60ef6 100644
--- a/src/main/java/com/maxmind/geoip2/model/EnterpriseResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/EnterpriseResponse.java
@@ -1,10 +1,9 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
-import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Continent;
import com.maxmind.geoip2.record.Country;
@@ -22,58 +21,277 @@
* This class provides a model for the data returned by the GeoIP2 Enterprise
* database
*
+ *
+ * @param city City record for the requested IP address.
+ * @param continent Continent record for the requested IP address.
+ * @param country Country record for the requested IP address. This object represents the country
+ * where MaxMind believes the end user is located.
+ * @param location Location record for the requested IP address.
+ * @param maxmind MaxMind record containing data related to your account.
+ * @param postal Postal record for the requested IP address.
+ * @param registeredCountry Registered country record for the requested IP address. This record
+ * represents the country where the ISP has registered a given IP block
+ * and may differ from the user's country.
+ * @param representedCountry Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the country.
+ * @param subdivisions An {@link List} of {@link Subdivision} objects representing the country
+ * subdivisions for the requested IP address. The number and type of
+ * subdivisions varies by country, but a subdivision is typically a state,
+ * province, county, etc. Subdivisions are ordered from most general (largest)
+ * to most specific (smallest). If the response did not contain any
+ * subdivisions, this is an empty list.
+ * @param traits Record for the traits of the requested IP address.
*/
-public final class EnterpriseResponse extends AbstractCityResponse {
+public record EnterpriseResponse(
+ @JsonProperty("city")
+ @MaxMindDbParameter(name = "city")
+ City city,
+
+ @JsonProperty("continent")
+ @MaxMindDbParameter(name = "continent")
+ Continent continent,
+
+ @JsonProperty("country")
+ @MaxMindDbParameter(name = "country")
+ Country country,
+
+ @JsonProperty("location")
+ @MaxMindDbParameter(name = "location")
+ Location location,
+
+ @JsonProperty("maxmind")
+ @MaxMindDbParameter(name = "maxmind")
+ MaxMind maxmind,
+
+ @JsonProperty("postal")
+ @MaxMindDbParameter(name = "postal")
+ Postal postal,
+
+ @JsonProperty("registered_country")
+ @MaxMindDbParameter(name = "registered_country")
+ Country registeredCountry,
+
+ @JsonProperty("represented_country")
+ @MaxMindDbParameter(name = "represented_country")
+ RepresentedCountry representedCountry,
+
+ @JsonProperty("subdivisions")
+ @MaxMindDbParameter(name = "subdivisions")
+ List subdivisions,
+
+ @JsonProperty("traits")
+ @MaxMindDbParameter(name = "traits")
+ Traits traits
+) implements JsonSerializable {
/**
- * Constructs an instance of {@code EnterpriseResponse} with the specified parameters.
- *
- * @param city city
- * @param continent continent
- * @param country country
- * @param location location
- * @param maxmind maxmind record for the response
- * @param postal postal
- * @param registeredCountry registered country
- * @param representedCountry represented country
- * @param subdivisions subdivisions
- * @param traits traits
- */
- @MaxMindDbConstructor
- public EnterpriseResponse(
- @JsonProperty("city") @MaxMindDbParameter(name = "city") City city,
- @JsonProperty("continent") @MaxMindDbParameter(name = "continent") Continent continent,
- @JsonProperty("country") @MaxMindDbParameter(name = "country") Country country,
- @JsonProperty("location") @MaxMindDbParameter(name = "location") Location location,
- @JsonProperty("maxmind") @MaxMindDbParameter(name = "maxmind") MaxMind maxmind,
- @JsonProperty("postal") @MaxMindDbParameter(name = "postal") Postal postal,
- @JsonProperty("registered_country") @MaxMindDbParameter(name = "registered_country")
- Country registeredCountry,
- @JsonProperty("represented_country") @MaxMindDbParameter(name = "represented_country")
- RepresentedCountry representedCountry,
- @JsonProperty("subdivisions") @MaxMindDbParameter(name = "subdivisions")
- ArrayList subdivisions,
- @JsonProperty("traits") @MaxMindDbParameter(name = "traits")
- Traits traits
- ) {
- super(city, continent, country, location, maxmind, postal, registeredCountry,
- representedCountry, subdivisions, traits);
+ * Compact canonical constructor that sets defaults for null values.
+ */
+ public EnterpriseResponse {
+ city = city != null ? city : new City();
+ continent = continent != null ? continent : new Continent();
+ country = country != null ? country : new Country();
+ location = location != null ? location : new Location();
+ maxmind = maxmind != null ? maxmind : new MaxMind();
+ postal = postal != null ? postal : new Postal();
+ registeredCountry = registeredCountry != null ? registeredCountry : new Country();
+ representedCountry = representedCountry != null
+ ? representedCountry : new RepresentedCountry();
+ subdivisions = subdivisions != null ? List.copyOf(subdivisions) : List.of();
+ traits = traits != null ? traits : new Traits();
}
/**
* Constructs an instance of {@code EnterpriseResponse} with only required parameters.
*
* @param response the response
- * @param ipAddress the IP address that the data in the model is for.
- * @param network the network associated with the record.
* @param locales the locales
*/
public EnterpriseResponse(
EnterpriseResponse response,
- String ipAddress,
- Network network,
List locales
) {
- super(response, ipAddress, network, locales);
+ this(
+ new City(response.city(), locales),
+ new Continent(response.continent(), locales),
+ new Country(response.country(), locales),
+ response.location(),
+ response.maxmind(),
+ response.postal(),
+ new Country(response.registeredCountry(), locales),
+ new RepresentedCountry(response.representedCountry(), locales),
+ mapSubdivisions(response.subdivisions(), locales),
+ response.traits()
+ );
+ }
+
+ private static ArrayList mapSubdivisions(
+ List subdivisions,
+ List locales
+ ) {
+ var subdivisions2 = new ArrayList(subdivisions.size());
+ for (var subdivision : subdivisions) {
+ subdivisions2.add(new Subdivision(subdivision, locales));
+ }
+ return subdivisions2;
+ }
+
+ /**
+ * @return City record for the requested IP address.
+ * @deprecated Use {@link #city()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public City getCity() {
+ return city();
+ }
+
+ /**
+ * @return Continent record for the requested IP address.
+ * @deprecated Use {@link #continent()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Continent getContinent() {
+ return continent();
+ }
+
+ /**
+ * @return Country record for the requested IP address. This object
+ * represents the country where MaxMind believes the end user is
+ * located.
+ * @deprecated Use {@link #country()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Country getCountry() {
+ return country();
+ }
+
+ /**
+ * @return Location record for the requested IP address.
+ * @deprecated Use {@link #location()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Location getLocation() {
+ return location();
+ }
+
+ /**
+ * @return MaxMind record containing data related to your account.
+ * @deprecated Use {@link #maxmind()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("maxmind")
+ public MaxMind getMaxMind() {
+ return maxmind();
+ }
+
+ /**
+ * @return the postal
+ * @deprecated Use {@link #postal()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Postal getPostal() {
+ return postal();
+ }
+
+ /**
+ * @return Registered country record for the requested IP address. This
+ * record represents the country where the ISP has registered a
+ * given IP block and may differ from the user's country.
+ * @deprecated Use {@link #registeredCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("registered_country")
+ public Country getRegisteredCountry() {
+ return registeredCountry();
+ }
+
+ /**
+ * @return Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the
+ * country.
+ * @deprecated Use {@link #representedCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("represented_country")
+ public RepresentedCountry getRepresentedCountry() {
+ return representedCountry();
+ }
+
+ /**
+ * @return An {@link List} of {@link Subdivision} objects representing the
+ * country subdivisions for the requested IP address. The number and
+ * type of subdivisions varies by country, but a subdivision is
+ * typically a state, province, county, etc. Subdivisions are
+ * ordered from most general (largest) to most specific (smallest).
+ * If the response did not contain any subdivisions, this method
+ * returns an empty array.
+ * @deprecated Use {@link #subdivisions()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public List getSubdivisions() {
+ return new ArrayList<>(subdivisions());
+ }
+
+ /**
+ * @return Record for the traits of the requested IP address.
+ * @deprecated Use {@link #traits()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Traits getTraits() {
+ return traits();
+ }
+
+ /**
+ * @return An object representing the most specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ */
+ @JsonIgnore
+ public Subdivision mostSpecificSubdivision() {
+ if (subdivisions().isEmpty()) {
+ return new Subdivision();
+ }
+ return subdivisions().get(subdivisions().size() - 1);
+ }
+
+ /**
+ * @return An object representing the most specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ * @deprecated Use {@link #mostSpecificSubdivision()} instead. This method will be removed
+ * in 6.0.0.
+ */
+ @JsonIgnore
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Subdivision getMostSpecificSubdivision() {
+ return mostSpecificSubdivision();
+ }
+
+ /**
+ * @return An object representing the least specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ */
+ @JsonIgnore
+ public Subdivision leastSpecificSubdivision() {
+ if (subdivisions().isEmpty()) {
+ return new Subdivision();
+ }
+ return subdivisions().get(0);
+ }
+
+ /**
+ * @return An object representing the least specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ * @deprecated Use {@link #leastSpecificSubdivision()} instead. This method will be removed
+ * in 6.0.0.
+ */
+ @JsonIgnore
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Subdivision getLeastSpecificSubdivision() {
+ return leastSpecificSubdivision();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/InsightsResponse.java b/src/main/java/com/maxmind/geoip2/model/InsightsResponse.java
index b96bceb7..2358153e 100644
--- a/src/main/java/com/maxmind/geoip2/model/InsightsResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/InsightsResponse.java
@@ -1,7 +1,8 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Continent;
import com.maxmind.geoip2.record.Country;
@@ -11,43 +12,240 @@
import com.maxmind.geoip2.record.RepresentedCountry;
import com.maxmind.geoip2.record.Subdivision;
import com.maxmind.geoip2.record.Traits;
+import java.util.ArrayList;
import java.util.List;
/**
* This class provides a model for the data returned by the Insights web
* service.
*
+ * @param city City record for the requested IP address.
+ * @param continent Continent record for the requested IP address.
+ * @param country Country record for the requested IP address. This object represents the country
+ * where MaxMind believes the end user is located.
+ * @param location Location record for the requested IP address.
+ * @param maxmind MaxMind record containing data related to your account.
+ * @param postal Postal record for the requested IP address.
+ * @param registeredCountry Registered country record for the requested IP address. This record
+ * represents the country where the ISP has registered a given IP block
+ * and may differ from the user's country.
+ * @param representedCountry Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the country.
+ * @param subdivisions An {@link List} of {@link Subdivision} objects representing the country
+ * subdivisions for the requested IP address. The number and type of
+ * subdivisions varies by country, but a subdivision is typically a state,
+ * province, county, etc. Subdivisions are ordered from most general (largest)
+ * to most specific (smallest). If the response did not contain any
+ * subdivisions, this is an empty list.
+ * @param traits Record for the traits of the requested IP address.
* @see GeoIP2 Web
* Services
*/
-public class InsightsResponse extends AbstractCityResponse {
- /**
- * Constructs an instance of {@code InsightsResponse} with the specified parameters.
- *
- * @param city city
- * @param continent continent
- * @param country country
- * @param location location
- * @param maxmind maxmind record for the response
- * @param postal postal
- * @param registeredCountry registered country
- * @param representedCountry represented country
- * @param subdivisions subdivisions
- * @param traits traits
- */
- public InsightsResponse(
- @JsonProperty("city") City city,
- @JsonProperty("continent") Continent continent,
- @JsonProperty("country") Country country,
- @JsonProperty("location") Location location,
- @JsonProperty("maxmind") MaxMind maxmind,
- @JsonProperty("postal") Postal postal,
- @JsonProperty("registered_country") Country registeredCountry,
- @JsonProperty("represented_country") RepresentedCountry representedCountry,
- @JsonProperty("subdivisions") List subdivisions,
- @JsonProperty("traits") Traits traits
- ) {
- super(city, continent, country, location, maxmind, postal, registeredCountry,
- representedCountry, subdivisions, traits);
+public record InsightsResponse(
+ @JsonProperty("city")
+ City city,
+
+ @JsonProperty("continent")
+ Continent continent,
+
+ @JsonProperty("country")
+ Country country,
+
+ @JsonProperty("location")
+ Location location,
+
+ @JsonProperty("maxmind")
+ MaxMind maxmind,
+
+ @JsonProperty("postal")
+ Postal postal,
+
+ @JsonProperty("registered_country")
+ Country registeredCountry,
+
+ @JsonProperty("represented_country")
+ RepresentedCountry representedCountry,
+
+ @JsonProperty("subdivisions")
+ List subdivisions,
+
+ @JsonProperty("traits")
+ Traits traits
+) implements JsonSerializable {
+
+ /**
+ * Compact canonical constructor that sets defaults for null values.
+ */
+ public InsightsResponse {
+ city = city != null ? city : new City();
+ continent = continent != null ? continent : new Continent();
+ country = country != null ? country : new Country();
+ location = location != null ? location : new Location();
+ maxmind = maxmind != null ? maxmind : new MaxMind();
+ postal = postal != null ? postal : new Postal();
+ registeredCountry = registeredCountry != null ? registeredCountry : new Country();
+ representedCountry = representedCountry != null
+ ? representedCountry : new RepresentedCountry();
+ subdivisions = subdivisions != null ? List.copyOf(subdivisions) : List.of();
+ traits = traits != null ? traits : new Traits();
+ }
+
+ /**
+ * @return City record for the requested IP address.
+ * @deprecated Use {@link #city()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public City getCity() {
+ return city();
+ }
+
+ /**
+ * @return Continent record for the requested IP address.
+ * @deprecated Use {@link #continent()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Continent getContinent() {
+ return continent();
+ }
+
+ /**
+ * @return Country record for the requested IP address. This object
+ * represents the country where MaxMind believes the end user is
+ * located.
+ * @deprecated Use {@link #country()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Country getCountry() {
+ return country();
+ }
+
+ /**
+ * @return Location record for the requested IP address.
+ * @deprecated Use {@link #location()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Location getLocation() {
+ return location();
+ }
+
+ /**
+ * @return MaxMind record containing data related to your account.
+ * @deprecated Use {@link #maxmind()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("maxmind")
+ public MaxMind getMaxMind() {
+ return maxmind();
+ }
+
+ /**
+ * @return the postal
+ * @deprecated Use {@link #postal()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Postal getPostal() {
+ return postal();
+ }
+
+ /**
+ * @return Registered country record for the requested IP address. This
+ * record represents the country where the ISP has registered a
+ * given IP block and may differ from the user's country.
+ * @deprecated Use {@link #registeredCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("registered_country")
+ public Country getRegisteredCountry() {
+ return registeredCountry();
+ }
+
+ /**
+ * @return Represented country record for the requested IP address. The
+ * represented country is used for things like military bases. It is
+ * only present when the represented country differs from the
+ * country.
+ * @deprecated Use {@link #representedCountry()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("represented_country")
+ public RepresentedCountry getRepresentedCountry() {
+ return representedCountry();
+ }
+
+ /**
+ * @return An {@link List} of {@link Subdivision} objects representing the
+ * country subdivisions for the requested IP address. The number and
+ * type of subdivisions varies by country, but a subdivision is
+ * typically a state, province, county, etc. Subdivisions are
+ * ordered from most general (largest) to most specific (smallest).
+ * If the response did not contain any subdivisions, this method
+ * returns an empty array.
+ * @deprecated Use {@link #subdivisions()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public List getSubdivisions() {
+ return new ArrayList<>(subdivisions());
+ }
+
+ /**
+ * @return Record for the traits of the requested IP address.
+ * @deprecated Use {@link #traits()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Traits getTraits() {
+ return traits();
+ }
+
+ /**
+ * @return An object representing the most specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ */
+ @JsonIgnore
+ public Subdivision mostSpecificSubdivision() {
+ if (subdivisions().isEmpty()) {
+ return new Subdivision();
+ }
+ return subdivisions().get(subdivisions().size() - 1);
+ }
+
+ /**
+ * @return An object representing the most specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ * @deprecated Use {@link #mostSpecificSubdivision()} instead. This method will be removed
+ * in 6.0.0.
+ */
+ @JsonIgnore
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Subdivision getMostSpecificSubdivision() {
+ return mostSpecificSubdivision();
+ }
+
+ /**
+ * @return An object representing the least specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ */
+ @JsonIgnore
+ public Subdivision leastSpecificSubdivision() {
+ if (subdivisions().isEmpty()) {
+ return new Subdivision();
+ }
+ return subdivisions().get(0);
+ }
+
+ /**
+ * @return An object representing the least specific subdivision returned. If
+ * the response did not contain any subdivisions, this method
+ * returns an empty {@link Subdivision} object.
+ * @deprecated Use {@link #leastSpecificSubdivision()} instead. This method will be removed
+ * in 6.0.0.
+ */
+ @JsonIgnore
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Subdivision getLeastSpecificSubdivision() {
+ return leastSpecificSubdivision();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/IpBaseResponse.java b/src/main/java/com/maxmind/geoip2/model/IpBaseResponse.java
deleted file mode 100644
index fa3f65d3..00000000
--- a/src/main/java/com/maxmind/geoip2/model/IpBaseResponse.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.maxmind.geoip2.model;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.maxmind.db.Network;
-
-/**
- * This class provides the base IP model.
- */
-public class IpBaseResponse extends AbstractResponse {
-
- private final boolean isAnonymous;
- private final boolean isAnonymousVpn;
- private final boolean isHostingProvider;
- private final boolean isPublicProxy;
- private final boolean isResidentialProxy;
- private final boolean isTorExitNode;
- private final String ipAddress;
- private final Network network;
-
- /**
- * Constructs an instance of {@code IpBaseResponse}.
- *
- * @param ipAddress the IP address that the data in the model is for
- * @param isAnonymous whether the IP address belongs to any sort of anonymous network
- * @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
- * @param isHostingProvider whether the IP address belongs to a hosting provider
- * @param isPublicProxy whether the IP address belongs to a public proxy system
- * @param isResidentialProxy whether the IP address belongs to a residential proxy system
- * @param isTorExitNode whether the IP address is a Tor exit node
- * @param network the network associated with the record
- */
- public IpBaseResponse(
- String ipAddress,
- boolean isAnonymous,
- boolean isAnonymousVpn,
- boolean isHostingProvider,
- boolean isPublicProxy,
- boolean isResidentialProxy,
- boolean isTorExitNode,
- Network network
- ) {
- this.isAnonymous = isAnonymous;
- this.isAnonymousVpn = isAnonymousVpn;
- this.isHostingProvider = isHostingProvider;
- this.isPublicProxy = isPublicProxy;
- this.isResidentialProxy = isResidentialProxy;
- this.isTorExitNode = isTorExitNode;
- this.ipAddress = ipAddress;
- this.network = network;
- }
-
- /**
- * @return whether the IP address belongs to any sort of anonymous network.
- */
- @JsonProperty("is_anonymous")
- public boolean isAnonymous() {
- return isAnonymous;
- }
-
- /**
- * @return whether the IP address is registered to an anonymous VPN
- * provider. If a VPN provider does not register subnets under names
- * associated with them, we will likely only flag their IP ranges using
- * isHostingProvider.
- */
- @JsonProperty("is_anonymous_vpn")
- public boolean isAnonymousVpn() {
- return isAnonymousVpn;
- }
-
- /**
- * @return whether the IP address belongs to a hosting or VPN provider
- * (see description of isAnonymousVpn).
- */
- @JsonProperty("is_hosting_provider")
- public boolean isHostingProvider() {
- return isHostingProvider;
- }
-
- /**
- * @return whether the IP address belongs to a public proxy.
- */
- @JsonProperty("is_public_proxy")
- public boolean isPublicProxy() {
- return isPublicProxy;
- }
-
- /**
- * @return whether the IP address is on a suspected anonymizing network and
- * belongs to a residential ISP.
- */
- @JsonProperty("is_residential_proxy")
- public boolean isResidentialProxy() {
- return isResidentialProxy;
- }
-
- /**
- * @return whether the IP address is a Tor exit node.
- */
- @JsonProperty("is_tor_exit_node")
- public boolean isTorExitNode() {
- return isTorExitNode;
- }
-
- /**
- * @return The IP address that the data in the model is for.
- */
- @JsonProperty("ip_address")
- public String getIpAddress() {
- return this.ipAddress;
- }
-
- /**
- * @return The network associated with the record. In particular, this is
- * the largest network where all the fields besides IP address have the
- * same value.
- */
- @JsonProperty
- @JsonSerialize(using = ToStringSerializer.class)
- public Network getNetwork() {
- return this.network;
- }
-}
diff --git a/src/main/java/com/maxmind/geoip2/model/IpRiskResponse.java b/src/main/java/com/maxmind/geoip2/model/IpRiskResponse.java
index 4d66c694..4795ae18 100644
--- a/src/main/java/com/maxmind/geoip2/model/IpRiskResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/IpRiskResponse.java
@@ -1,122 +1,104 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
/**
* This class provides the GeoIP2 IP Risk model.
*
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param isAnonymous Whether the IP address belongs to any sort of anonymous network.
+ * @param isAnonymousVpn Whether the IP address is registered to an anonymous VPN provider. If a
+ * VPN provider does not register subnets under names associated with them,
+ * we will likely only flag their IP ranges using isHostingProvider.
+ * @param isHostingProvider Whether the IP address belongs to a hosting or VPN provider (see
+ * description of isAnonymousVpn).
+ * @param isPublicProxy Whether the IP address belongs to a public proxy.
+ * @param isResidentialProxy Whether the IP address is on a suspected anonymizing network and
+ * belongs to a residential ISP.
+ * @param isTorExitNode Whether the IP address is a Tor exit node.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
+ * @param ipRisk The IP risk of a model.
*/
-public class IpRiskResponse extends IpBaseResponse {
+public record IpRiskResponse(
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
- private final double ipRisk;
+ @JsonProperty("is_anonymous")
+ @MaxMindDbParameter(name = "is_anonymous", useDefault = true)
+ boolean isAnonymous,
- /**
- * Constructs an instance of {@code IpRiskResponse}.
- *
- * @param ipAddress the IP address being checked
- * @param isAnonymous whether the IP address belongs to any sort of anonymous network
- * @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
- * @param isHostingProvider whether the IP address belongs to a hosting provider
- * @param isPublicProxy whether the IP address belongs to a public proxy system
- * @param isResidentialProxy whether the IP address belongs to a residential proxy system
- * @param isTorExitNode whether the IP address is a Tor exit node
- * @param network the network associated with the record
- * @param ipRisk the IP risk of a model
- */
- public IpRiskResponse(
- @JsonProperty("ip_address") String ipAddress,
- @JsonProperty("is_anonymous") boolean isAnonymous,
- @JsonProperty("is_anonymous_vpn") boolean isAnonymousVpn,
- @JsonProperty("is_hosting_provider") boolean isHostingProvider,
- @JsonProperty("is_public_proxy") boolean isPublicProxy,
- @JsonProperty("is_residential_proxy") boolean isResidentialProxy,
- @JsonProperty("is_tor_exit_node") boolean isTorExitNode,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) Network network,
- @JsonProperty("ip_risk") double ipRisk
- ) {
- super(ipAddress, isAnonymous, isAnonymousVpn, isHostingProvider, isPublicProxy,
- isResidentialProxy, isTorExitNode, network);
- this.ipRisk = ipRisk;
- }
+ @JsonProperty("is_anonymous_vpn")
+ @MaxMindDbParameter(name = "is_anonymous_vpn", useDefault = true)
+ boolean isAnonymousVpn,
- /**
- * Constructs an instance of {@code IpRiskResponse}.
- *
- * @param ipAddress the IP address being checked
- * @param isAnonymous whether the IP address belongs to any sort of anonymous network
- * @param isAnonymousVpn whether the IP address belongs to an anonymous VPN system
- * @param isHostingProvider whether the IP address belongs to a hosting provider
- * @param isPublicProxy whether the IP address belongs to a public proxy system
- * @param isResidentialProxy whether the IP address belongs to a residential proxy system
- * @param isTorExitNode whether the IP address is a Tor exit node
- * @param network the network associated with the record
- * @param ipRisk the IP risk of a model
- *
- */
- @MaxMindDbConstructor
- public IpRiskResponse(
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @MaxMindDbParameter(name = "is_anonymous") Boolean isAnonymous,
- @MaxMindDbParameter(name = "is_anonymous_vpn") Boolean isAnonymousVpn,
- @MaxMindDbParameter(name = "is_hosting_provider") Boolean isHostingProvider,
- @MaxMindDbParameter(name = "is_public_proxy") Boolean isPublicProxy,
- @MaxMindDbParameter(name = "is_residential_proxy") Boolean isResidentialProxy,
- @MaxMindDbParameter(name = "is_tor_exit_node") Boolean isTorExitNode,
- @MaxMindDbParameter(name = "network") Network network,
- @MaxMindDbParameter(name = "ip_risk") double ipRisk
+ @JsonProperty("is_hosting_provider")
+ @MaxMindDbParameter(name = "is_hosting_provider", useDefault = true)
+ boolean isHostingProvider,
+
+ @JsonProperty("is_public_proxy")
+ @MaxMindDbParameter(name = "is_public_proxy", useDefault = true)
+ boolean isPublicProxy,
- ) {
- this(
- ipAddress,
- isAnonymous != null ? isAnonymous : false,
- isAnonymousVpn != null ? isAnonymousVpn : false,
- isHostingProvider != null ? isHostingProvider : false,
- isPublicProxy != null ? isPublicProxy : false,
- isResidentialProxy != null ? isResidentialProxy : false,
- isTorExitNode != null ? isTorExitNode : false,
- network,
- ipRisk
+ @JsonProperty("is_residential_proxy")
+ @MaxMindDbParameter(name = "is_residential_proxy", useDefault = true)
+ boolean isResidentialProxy,
- );
+ @JsonProperty("is_tor_exit_node")
+ @MaxMindDbParameter(name = "is_tor_exit_node", useDefault = true)
+ boolean isTorExitNode,
+
+ @JsonProperty("network")
+ @MaxMindDbNetwork
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ Network network,
+
+ @JsonProperty("ip_risk")
+ @MaxMindDbParameter(name = "ip_risk")
+ double ipRisk
+) implements JsonSerializable {
+
+ /**
+ * @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("ip_address")
+ public String getIpAddress() {
+ return ipAddress().getHostAddress();
}
/**
- * Constructs an instance of {@code IpRiskResponse}.
- *
- * @param response The {@code IpRiskResponse} object to copy.
- * @param ipAddress The IP address that the data in the model is for.
- * @param network The network associated with the record.
+ * @return The network associated with the record. In particular, this is
+ * the largest network where all the fields besides IP address have the
+ * same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
*/
- public IpRiskResponse(
- IpRiskResponse response,
- String ipAddress,
- Network network
- ) {
- this(
- ipAddress,
- response.isAnonymous(),
- response.isAnonymousVpn(),
- response.isHostingProvider(),
- response.isPublicProxy(),
- response.isResidentialProxy(),
- response.isTorExitNode(),
- network,
- response.ipRisk
- );
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty
+ @JsonSerialize(using = ToStringSerializer.class)
+ public Network getNetwork() {
+ return network();
}
/**
* @return The IP risk of a model.
+ * @deprecated Use {@link #ipRisk()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("ip_risk")
public double getIpRisk() {
- return this.ipRisk;
+ return ipRisk();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/model/IspResponse.java b/src/main/java/com/maxmind/geoip2/model/IspResponse.java
index 3bc9f2d5..612816b4 100644
--- a/src/main/java/com/maxmind/geoip2/model/IspResponse.java
+++ b/src/main/java/com/maxmind/geoip2/model/IspResponse.java
@@ -1,94 +1,112 @@
package com.maxmind.geoip2.model;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
+import java.net.InetAddress;
/**
* This class provides the GeoIP2 ISP model.
+ *
+ * @param autonomousSystemNumber The autonomous system number associated with the IP address.
+ * @param autonomousSystemOrganization The organization associated with the registered autonomous
+ * system number for the IP address.
+ * @param ipAddress The IP address that the data in the model is for.
+ * @param isp The name of the ISP associated with the IP address.
+ * @param mobileCountryCode The
+ * mobile country code (MCC) associated with the IP address and ISP.
+ * This property is available from the City and Insights web services and
+ * the GeoIP2 Enterprise database.
+ * @param mobileNetworkCode The
+ * mobile network code (MNC) associated with the IP address and ISP.
+ * This property is available from the City and Insights web services and
+ * the GeoIP2 Enterprise database.
+ * @param organization The name of the organization associated with the IP address.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
*/
-public class IspResponse extends AsnResponse {
+public record IspResponse(
+ @JsonProperty("autonomous_system_number")
+ @MaxMindDbParameter(name = "autonomous_system_number")
+ Long autonomousSystemNumber,
- private final String isp;
- private final String organization;
- private final String mobileCountryCode;
- private final String mobileNetworkCode;
+ @JsonProperty("autonomous_system_organization")
+ @MaxMindDbParameter(name = "autonomous_system_organization")
+ String autonomousSystemOrganization,
+
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
+
+ @JsonProperty("isp")
+ @MaxMindDbParameter(name = "isp")
+ String isp,
+
+ @JsonProperty("mobile_country_code")
+ @MaxMindDbParameter(name = "mobile_country_code")
+ String mobileCountryCode,
+
+ @JsonProperty("mobile_network_code")
+ @MaxMindDbParameter(name = "mobile_network_code")
+ String mobileNetworkCode,
+
+ @JsonProperty("organization")
+ @MaxMindDbParameter(name = "organization")
+ String organization,
+
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @MaxMindDbNetwork
+ Network network
+) implements JsonSerializable {
/**
- * Constructs an instance of {@code IspResponse}.
- *
- * @param autonomousSystemNumber the autonomous system number associated with the IP
- * address
- * @param autonomousSystemOrganization the organization associated with the registered
- * autonomous system number for the IP address
- * @param ipAddress the IP address that the data in the model is for
- * @param isp the name of the ISP associated with the IP address
- * @param mobileCountryCode the mobile country code (MCC) associated with the IP
- * @param mobileNetworkCode the mobile network code (MNC) associated with the IP
- * @param organization the name of the organization associated with the IP
- * address
- * @param network the network associated with the record
+ * @return The autonomous system number associated with the IP address.
+ * @deprecated Use {@link #autonomousSystemNumber()} instead. This method will be removed
+ * in 6.0.0.
*/
- @MaxMindDbConstructor
- public IspResponse(
- @JsonProperty("autonomous_system_number")
- @MaxMindDbParameter(name = "autonomous_system_number") Long autonomousSystemNumber,
- @JsonProperty("autonomous_system_organization")
- @MaxMindDbParameter(name = "autonomous_system_organization")
- String autonomousSystemOrganization,
- @JsonProperty("ip_address")
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @JsonProperty("isp") @MaxMindDbParameter(name = "isp") String isp,
- @JsonProperty("mobile_country_code") @MaxMindDbParameter(name = "mobile_country_code")
- String mobileCountryCode,
- @JsonProperty("mobile_network_code") @MaxMindDbParameter(name = "mobile_network_code")
- String mobileNetworkCode,
- @JsonProperty("organization") @MaxMindDbParameter(name = "organization")
- String organization,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) @MaxMindDbParameter(name = "network")
- Network network
- ) {
- super(autonomousSystemNumber, autonomousSystemOrganization, ipAddress, network);
- this.isp = isp;
- this.mobileCountryCode = mobileCountryCode;
- this.mobileNetworkCode = mobileNetworkCode;
- this.organization = organization;
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("autonomous_system_number")
+ public Long getAutonomousSystemNumber() {
+ return autonomousSystemNumber();
}
/**
- * Constructs an instance of {@code IspResponse}.
- *
- * @param response The {@code AsnResponse} object to copy.
- * @param ipAddress The IP address that the data in the model is for.
- * @param network The network associated with the record.
+ * @return The organization associated with the registered autonomous system
+ * number for the IP address
+ * @deprecated Use {@link #autonomousSystemOrganization()} instead. This method will be
+ * removed in 6.0.0.
*/
- public IspResponse(
- IspResponse response,
- String ipAddress,
- Network network
- ) {
- this(
- response.getAutonomousSystemNumber(),
- response.getAutonomousSystemOrganization(),
- ipAddress,
- response.getIsp(),
- response.getMobileCountryCode(),
- response.getMobileNetworkCode(),
- response.getOrganization(),
- network
- );
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("autonomous_system_organization")
+ public String getAutonomousSystemOrganization() {
+ return autonomousSystemOrganization();
+ }
+
+ /**
+ * @return The IP address that the data in the model is for.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("ip_address")
+ public String getIpAddress() {
+ return ipAddress().getHostAddress();
}
/**
* @return The name of the ISP associated with the IP address.
+ * @deprecated Use {@link #isp()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getIsp() {
- return this.isp;
+ return isp();
}
/**
@@ -96,10 +114,12 @@ public String getIsp() {
* mobile country code (MCC) associated with the IP address and ISP.
* This property is available from the City and Insights web services and
* the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #mobileCountryCode()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("mobile_country_code")
public String getMobileCountryCode() {
- return this.mobileCountryCode;
+ return mobileCountryCode();
}
/**
@@ -107,16 +127,33 @@ public String getMobileCountryCode() {
* mobile network code (MNC) associated with the IP address and ISP.
* This property is available from the City and Insights web services and
* the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #mobileNetworkCode()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("mobile_network_code")
public String getMobileNetworkCode() {
- return this.mobileNetworkCode;
+ return mobileNetworkCode();
}
/**
* @return The name of the organization associated with the IP address.
+ * @deprecated Use {@link #organization()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getOrganization() {
- return this.organization;
+ return organization();
+ }
+
+ /**
+ * @return The network associated with the record. In particular, this is
+ * the largest network where all the fields besides IP address have the
+ * same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty
+ @JsonSerialize(using = ToStringSerializer.class)
+ public Network getNetwork() {
+ return network();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/AbstractNamedRecord.java b/src/main/java/com/maxmind/geoip2/record/AbstractNamedRecord.java
deleted file mode 100644
index c3f644ae..00000000
--- a/src/main/java/com/maxmind/geoip2/record/AbstractNamedRecord.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.maxmind.geoip2.record;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Abstract class for records with name maps.
- */
-public abstract class AbstractNamedRecord extends AbstractRecord {
-
- private final Map names;
- private final Long geoNameId;
- private final List locales;
-
- AbstractNamedRecord() {
- this(null, null, null);
- }
-
- AbstractNamedRecord(List locales, Long geoNameId, Map names) {
- this.names = names != null ? names : new HashMap<>();
- this.geoNameId = geoNameId;
- this.locales = locales != null ? locales : new ArrayList<>();
- }
-
- /**
- * @return The GeoName ID for the city.
- */
- @JsonProperty("geoname_id")
- public Long getGeoNameId() {
- return this.geoNameId;
- }
-
- /**
- * @return The name of the city based on the locales list passed to the
- * constructor.
- */
- @JsonIgnore
- public String getName() {
- for (String lang : this.locales) {
- if (this.names.containsKey(lang)) {
- return this.names.get(lang);
- }
- }
- return null;
- }
-
- /**
- * @return A {@link Map} from locale codes to the name in that locale.
- */
- @JsonProperty("names")
- public Map getNames() {
- return new HashMap<>(this.names);
- }
-}
diff --git a/src/main/java/com/maxmind/geoip2/record/City.java b/src/main/java/com/maxmind/geoip2/record/City.java
index 98b5da9e..2ba14b2c 100644
--- a/src/main/java/com/maxmind/geoip2/record/City.java
+++ b/src/main/java/com/maxmind/geoip2/record/City.java
@@ -2,8 +2,8 @@
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.NamedRecord;
import java.util.List;
import java.util.Map;
@@ -13,38 +13,47 @@
*
*
* Do not use any of the city names as a database or map key. Use the value
- * returned by {@link #getGeoNameId} instead.
+ * returned by {@link #geonameId()} instead.
*
+ *
+ * @param locales The locales to use for retrieving localized names.
+ * @param confidence A value from 0-100 indicating MaxMind's confidence that the city
+ * is correct. This attribute is only available from the Insights
+ * web service and the GeoIP2 Enterprise database.
+ * @param geonameId The GeoName ID for the city.
+ * @param names A {@link Map} from locale codes to the name in that locale.
*/
-public final class City extends AbstractNamedRecord {
+public record City(
+ @JacksonInject("locales")
+ @MaxMindDbParameter(name = "locales")
+ List locales,
- private final Integer confidence;
+ @JsonProperty("confidence")
+ @MaxMindDbParameter(name = "confidence")
+ Integer confidence,
+
+ @JsonProperty("geoname_id")
+ @MaxMindDbParameter(name = "geoname_id")
+ Long geonameId,
+
+ @JsonProperty("names")
+ @MaxMindDbParameter(name = "names")
+ Map names
+) implements NamedRecord {
/**
- * Constructs an instance of {@code City} with no data.
+ * Compact canonical constructor that ensures immutability and handles null values.
*/
- public City() {
- this(null, null, null, null);
+ public City {
+ locales = locales != null ? List.copyOf(locales) : List.of();
+ names = names != null ? Map.copyOf(names) : Map.of();
}
/**
- * Constructs an instance of {@code City} with the specified parameters.
- *
- * @param locales The locales to use.
- * @param confidence A value from 0-100 indicating MaxMind's confidence that the
- * city is correct. .
- * @param geoNameId The GeoName ID for the city.
- * @param names A map from locale codes to the city name in that locale.
+ * Constructs an instance of {@code City} with no data.
*/
- @MaxMindDbConstructor
- public City(
- @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
- @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence,
- @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
- @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names
- ) {
- super(locales, geoNameId, names);
- this.confidence = confidence;
+ public City() {
+ this(null, null, null, null);
}
/**
@@ -59,9 +68,9 @@ public City(
) {
this(
locales,
- city.getConfidence(),
- city.getGeoNameId(),
- city.getNames()
+ city.confidence(),
+ city.geonameId(),
+ city.names()
);
}
@@ -69,8 +78,41 @@ public City(
* @return A value from 0-100 indicating MaxMind's confidence that the city
* is correct. This attribute is only available from the Insights
* web service and the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #confidence()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public Integer getConfidence() {
- return this.confidence;
+ return confidence();
+ }
+
+ /**
+ * @return The GeoName ID for the city.
+ * @deprecated Use {@link #geonameId()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("geoname_id")
+ public Long getGeoNameId() {
+ return geonameId();
+ }
+
+ /**
+ * @return The name of the city based on the locales list passed to the
+ * constructor.
+ * @deprecated Use {@link #name()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @com.fasterxml.jackson.annotation.JsonIgnore
+ public String getName() {
+ return name();
+ }
+
+ /**
+ * @return A {@link Map} from locale codes to the name in that locale.
+ * @deprecated Use {@link #names()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("names")
+ public Map getNames() {
+ return names();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/Continent.java b/src/main/java/com/maxmind/geoip2/record/Continent.java
index a103f3dc..968e100a 100644
--- a/src/main/java/com/maxmind/geoip2/record/Continent.java
+++ b/src/main/java/com/maxmind/geoip2/record/Continent.java
@@ -2,8 +2,8 @@
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.NamedRecord;
import java.util.List;
import java.util.Map;
@@ -13,38 +13,46 @@
*
*
* Do not use any of the continent names as a database or map key. Use the
- * value returned by {@link #getGeoNameId} or {@link #getCode} instead.
+ * value returned by {@link #geonameId()} or {@link #code()} instead.
*
+ *
+ * @param locales The locales to use for retrieving localized names.
+ * @param code A two character continent code like "NA" (North America) or "OC"
+ * (Oceania).
+ * @param geonameId The GeoName ID for the continent.
+ * @param names A {@link Map} from locale codes to the name in that locale.
*/
-public final class Continent extends AbstractNamedRecord {
+public record Continent(
+ @JacksonInject("locales")
+ @MaxMindDbParameter(name = "locales")
+ List locales,
- private final String code;
+ @JsonProperty("code")
+ @MaxMindDbParameter(name = "code")
+ String code,
+
+ @JsonProperty("geoname_id")
+ @MaxMindDbParameter(name = "geoname_id")
+ Long geonameId,
+
+ @JsonProperty("names")
+ @MaxMindDbParameter(name = "names")
+ Map names
+) implements NamedRecord {
/**
- * Constructs an instance of {@code Continent} with no data.
+ * Compact canonical constructor that ensures immutability and handles null values.
*/
- public Continent() {
- this(null, null, null, null);
+ public Continent {
+ locales = locales != null ? List.copyOf(locales) : List.of();
+ names = names != null ? Map.copyOf(names) : Map.of();
}
/**
- * Constructs an instance of {@code Continent}.
- *
- * @param locales The locales to use.
- * @param code A two character continent code like "NA" (North America) or
- * "OC" (Oceania).
- * @param geoNameId The GeoName ID for the continent.
- * @param names A map from locale codes to the continent names.
+ * Constructs an instance of {@code Continent} with no data.
*/
- @MaxMindDbConstructor
- public Continent(
- @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
- @JsonProperty("code") @MaxMindDbParameter(name = "code") String code,
- @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
- @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names
- ) {
- super(locales, geoNameId, names);
- this.code = code;
+ public Continent() {
+ this(null, null, null, null);
}
/**
@@ -59,18 +67,49 @@ public Continent(
) {
this(
locales,
- continent.getCode(),
- continent.getGeoNameId(),
- continent.getNames()
+ continent.code(),
+ continent.geonameId(),
+ continent.names()
);
}
/**
* @return A two character continent code like "NA" (North America) or "OC"
* (Oceania).
+ * @deprecated Use {@link #code()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getCode() {
- return this.code;
+ return code();
}
+ /**
+ * @return The GeoName ID for the continent.
+ * @deprecated Use {@link #geonameId()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("geoname_id")
+ public Long getGeoNameId() {
+ return geonameId();
+ }
+
+ /**
+ * @return The name of the continent based on the locales list.
+ * @deprecated Use {@link #name()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @com.fasterxml.jackson.annotation.JsonIgnore
+ public String getName() {
+ return name();
+ }
+
+ /**
+ * @return A {@link Map} from locale codes to the name in that locale.
+ * @deprecated Use {@link #names()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("names")
+ public Map getNames() {
+ return names();
+ }
}
diff --git a/src/main/java/com/maxmind/geoip2/record/Country.java b/src/main/java/com/maxmind/geoip2/record/Country.java
index 1db6309d..17e4e699 100644
--- a/src/main/java/com/maxmind/geoip2/record/Country.java
+++ b/src/main/java/com/maxmind/geoip2/record/Country.java
@@ -2,8 +2,8 @@
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.NamedRecord;
import java.util.List;
import java.util.Map;
@@ -13,50 +13,59 @@
*
*
* Do not use any of the country names as a database or map key. Use the value
- * returned by {@link #getGeoNameId} or {@link #getIsoCode} instead.
+ * returned by {@link #geonameId()} or {@link #isoCode()} instead.
*
+ *
+ * @param locales The locales to use for retrieving localized names.
+ * @param confidence A value from 0-100 indicating MaxMind's confidence that the
+ * country is correct. This attribute is only available from the
+ * Insights web service and the GeoIP2 Enterprise database.
+ * @param geonameId The GeoName ID for the country.
+ * @param isInEuropeanUnion This is true if the country is a member state of the
+ * European Union.
+ * @param isoCode The two-character ISO
+ * 3166-1 alpha code for the country.
+ * @param names A {@link Map} from locale codes to the name in that locale.
*/
-public class Country extends AbstractNamedRecord {
+public record Country(
+ @JacksonInject("locales")
+ @MaxMindDbParameter(name = "locales")
+ List locales,
- private final Integer confidence;
- private final boolean isInEuropeanUnion;
- private final String isoCode;
+ @JsonProperty("confidence")
+ @MaxMindDbParameter(name = "confidence")
+ Integer confidence,
+
+ @JsonProperty("geoname_id")
+ @MaxMindDbParameter(name = "geoname_id")
+ Long geonameId,
+
+ @JsonProperty("is_in_european_union")
+ @MaxMindDbParameter(name = "is_in_european_union", useDefault = true)
+ boolean isInEuropeanUnion,
+
+ @JsonProperty("iso_code")
+ @MaxMindDbParameter(name = "iso_code")
+ String isoCode,
+
+ @JsonProperty("names")
+ @MaxMindDbParameter(name = "names")
+ Map names
+) implements NamedRecord {
/**
- * Constructs an instance of {@code Country} with no data.
+ * Compact canonical constructor that ensures immutability and handles null values.
*/
- public Country() {
- this(null, null, null, false, null, null);
+ public Country {
+ locales = locales != null ? List.copyOf(locales) : List.of();
+ names = names != null ? Map.copyOf(names) : Map.of();
}
- /**
- * Constructs an instance of {@code Country}.
- *
- * @param locales The locales to use.
- * @param confidence This is a value from 0-100 indicating MaxMind's
- * confidence that the country is correct.
- * @param geoNameId This is a GeoName ID for the country.
- * @param isInEuropeanUnion This is true if the country is a member state of
- * the European Union.
- * @param isoCode This is a string up to three characters long contain the
- * country code.
- * @param names This is a map from locale codes to the names for the country
- * in that locale.
+ /**
+ * Constructs an instance of {@code Country} with no data.
*/
- @MaxMindDbConstructor
- public Country(
- @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
- @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence,
- @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
- @JsonProperty("is_in_european_union") @MaxMindDbParameter(name = "is_in_european_union")
- Boolean isInEuropeanUnion,
- @JsonProperty("iso_code") @MaxMindDbParameter(name = "iso_code") String isoCode,
- @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names
- ) {
- super(locales, geoNameId, names);
- this.confidence = confidence;
- this.isInEuropeanUnion = isInEuropeanUnion != null ? isInEuropeanUnion : false;
- this.isoCode = isoCode;
+ public Country() {
+ this(null, null, null, false, null, null);
}
/**
@@ -71,11 +80,11 @@ public Country(
) {
this(
locales,
- country.getConfidence(),
- country.getGeoNameId(),
+ country.confidence(),
+ country.geonameId(),
country.isInEuropeanUnion(),
- country.getIsoCode(),
- country.getNames()
+ country.isoCode(),
+ country.names()
);
}
@@ -83,27 +92,52 @@ public Country(
* @return A value from 0-100 indicating MaxMind's confidence that the
* country is correct. This attribute is only available from the
* Insights web service and the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #confidence()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public Integer getConfidence() {
- return this.confidence;
- }
-
- /**
- * @return This is true if the country is a member state of the European
- * Union.
- */
- @JsonProperty("is_in_european_union")
- public boolean isInEuropeanUnion() {
- return this.isInEuropeanUnion;
+ return confidence();
}
/**
* @return The two-character ISO
* 3166-1 alpha code for the country.
+ * @deprecated Use {@link #isoCode()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("iso_code")
public String getIsoCode() {
- return this.isoCode;
+ return isoCode();
+ }
+
+ /**
+ * @return The GeoName ID for the country.
+ * @deprecated Use {@link #geonameId()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("geoname_id")
+ public Long getGeoNameId() {
+ return geonameId();
+ }
+
+ /**
+ * @return The name of the country based on the locales list.
+ * @deprecated Use {@link #name()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @com.fasterxml.jackson.annotation.JsonIgnore
+ public String getName() {
+ return name();
+ }
+
+ /**
+ * @return A {@link Map} from locale codes to the name in that locale.
+ * @deprecated Use {@link #names()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("names")
+ public Map getNames() {
+ return names();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/Location.java b/src/main/java/com/maxmind/geoip2/record/Location.java
index a1be28a2..846d3625 100644
--- a/src/main/java/com/maxmind/geoip2/record/Location.java
+++ b/src/main/java/com/maxmind/geoip2/record/Location.java
@@ -1,22 +1,60 @@
package com.maxmind.geoip2.record;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.JsonSerializable;
/**
*
* Contains data for the location record associated with an IP address.
*
+ *
+ * @param accuracyRadius The approximate accuracy radius in kilometers around the
+ * latitude and longitude for the IP address. This is the radius
+ * where we have a 67% confidence that the device using the IP
+ * address resides within the circle centered at the latitude and
+ * longitude with the provided radius.
+ * @param averageIncome The average income in US dollars associated with the requested
+ * IP address. This attribute is only available from the Insights
+ * web service.
+ * @param latitude The approximate latitude of the location associated with the IP
+ * address. This value is not precise and should not be used to identify
+ * a particular address or household.
+ * @param longitude The approximate longitude of the location associated with the IP
+ * address. This value is not precise and should not be used to identify
+ * a particular address or household.
+ * @param populationDensity The estimated population per square kilometer associated with
+ * the IP address. This attribute is only available from the
+ * Insights web service.
+ * @param timeZone The time zone associated with location, as specified by the
+ * IANA Time Zone Database,
+ * e.g., "America/New_York".
*/
-public class Location extends AbstractRecord {
+public record Location(
+ @JsonProperty("accuracy_radius")
+ @MaxMindDbParameter(name = "accuracy_radius")
+ Integer accuracyRadius,
+
+ @JsonProperty("average_income")
+ @MaxMindDbParameter(name = "average_income")
+ Integer averageIncome,
+
+ @JsonProperty("latitude")
+ @MaxMindDbParameter(name = "latitude")
+ Double latitude,
+
+ @JsonProperty("longitude")
+ @MaxMindDbParameter(name = "longitude")
+ Double longitude,
+
+ @JsonProperty("population_density")
+ @MaxMindDbParameter(name = "population_density")
+ Integer populationDensity,
- private final Integer accuracyRadius;
- private final Integer averageIncome;
- private final Double latitude;
- private final Double longitude;
- private final Integer populationDensity;
- private final String timeZone;
+ @JsonProperty("time_zone")
+ @MaxMindDbParameter(name = "time_zone")
+ String timeZone
+) implements JsonSerializable {
/**
* Constructs a {@code Location} record with {@code null} values for all the fields.
@@ -25,78 +63,40 @@ public Location() {
this(null, null, null, null, null, null);
}
- /**
- * Constructs an instance of {@code Location}.
- *
- * @param accuracyRadius The approximate accuracy radius in kilometers
- * around the latitude and longitude for the IP address. This is the radius
- * where we have a 67% confidence that the device using the IP address
- * resides within the circle centered at the latitude and longitude with
- * the provided radius.
- * @param averageIncome The average income in US dollars associated with
- * the requested IP address. This attribute is only available from the
- * Insights web service.
- * @param latitude The approximate latitude of the location associated
- * with the IP address. This value is not precise and should not be used
- * to identify a particular address or household.
- * @param longitude The approximate longitude of the location associated
- * with the IP address. This value is not precise and should not be used
- * to identify a particular address or household.
- * @param populationDensity The estimated population per square kilometer
- * associated with the IP address. This attribute is only available from
- * the Insights web service.
- * @param timeZone The time zone associated with location, as specified by
- * the IANA Time Zone
- * Database, e.g., "America/New_York".
- */
- @MaxMindDbConstructor
- public Location(
- @JsonProperty("accuracy_radius") @MaxMindDbParameter(name = "accuracy_radius")
- Integer accuracyRadius,
- @JsonProperty("average_income") @MaxMindDbParameter(name = "average_income")
- Integer averageIncome,
- @JsonProperty("latitude") @MaxMindDbParameter(name = "latitude") Double latitude,
- @JsonProperty("longitude") @MaxMindDbParameter(name = "longitude") Double longitude,
- @JsonProperty("population_density") @MaxMindDbParameter(name = "population_density")
- Integer populationDensity,
- @JsonProperty("time_zone") @MaxMindDbParameter(name = "time_zone") String timeZone
- ) {
- this.accuracyRadius = accuracyRadius;
- this.averageIncome = averageIncome;
- this.latitude = latitude;
- this.longitude = longitude;
- this.populationDensity = populationDensity;
- this.timeZone = timeZone;
- }
-
/**
* @return The average income in US dollars associated with the requested
* IP address. This attribute is only available from the Insights web
* service.
+ * @deprecated Use {@link #averageIncome()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("average_income")
public Integer getAverageIncome() {
- return this.averageIncome;
+ return averageIncome();
}
/**
* @return The estimated population per square kilometer associated with the
* IP address. This attribute is only available from the Insights web
* service.
+ * @deprecated Use {@link #populationDensity()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("population_density")
public Integer getPopulationDensity() {
- return this.populationDensity;
+ return populationDensity();
}
/**
* @return The time zone associated with location, as specified by the IANA Time Zone
* Database, e.g., "America/New_York".
+ * @deprecated Use {@link #timeZone()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("time_zone")
public String getTimeZone() {
- return this.timeZone;
+ return timeZone();
}
/**
@@ -105,28 +105,33 @@ public String getTimeZone() {
* have a 67% confidence that the device using the IP address resides
* within the circle centered at the latitude and longitude with the
* provided radius.
+ * @deprecated Use {@link #accuracyRadius()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("accuracy_radius")
public Integer getAccuracyRadius() {
- return this.accuracyRadius;
+ return accuracyRadius();
}
-
/**
* @return The approximate latitude of the location associated with the
* IP address. This value is not precise and should not be used to
* identify a particular address or household.
+ * @deprecated Use {@link #latitude()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public Double getLatitude() {
- return this.latitude;
+ return latitude();
}
/**
* @return The approximate longitude of the location associated with the
* IP address. This value is not precise and should not be used to
* identify a particular address or household.
+ * @deprecated Use {@link #longitude()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public Double getLongitude() {
- return this.longitude;
+ return longitude();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/MaxMind.java b/src/main/java/com/maxmind/geoip2/record/MaxMind.java
index 6bdd9ef6..a9380b89 100644
--- a/src/main/java/com/maxmind/geoip2/record/MaxMind.java
+++ b/src/main/java/com/maxmind/geoip2/record/MaxMind.java
@@ -1,17 +1,22 @@
package com.maxmind.geoip2.record;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.JsonSerializable;
/**
*
* Contains data related to your MaxMind account.
*
+ *
+ * @param queriesRemaining The number of remaining queries in your account for the current
+ * web service. This returns {@code null} when called on a database.
*/
-public final class MaxMind extends AbstractRecord {
-
- private final Integer queriesRemaining;
+public record MaxMind(
+ @JsonProperty("queries_remaining")
+ @MaxMindDbParameter(name = "queries_remaining")
+ Integer queriesRemaining
+) implements JsonSerializable {
/**
* Constructs a {@code MaxMind} record.
@@ -21,24 +26,13 @@ public MaxMind() {
}
/**
- * Constructs a {@code MaxMind} record.
- *
- * @param queriesRemaining The number of remaining queries in the current web service call.
- * This returns {@code null} when called on a database.
- */
- @MaxMindDbConstructor
- public MaxMind(
- @JsonProperty("queries_remaining") @MaxMindDbParameter(name = "queries_remaining")
- Integer queriesRemaining) {
- this.queriesRemaining = queriesRemaining;
- }
-
- /**
- * @return The number of remaining queried in your account for the current
+ * @return The number of remaining queries in your account for the current
* web service. This returns {@code null} when called on a database.
+ * @deprecated Use {@link #queriesRemaining()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("queries_remaining")
public Integer getQueriesRemaining() {
- return this.queriesRemaining;
+ return queriesRemaining();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/Postal.java b/src/main/java/com/maxmind/geoip2/record/Postal.java
index 05435116..be7680a5 100644
--- a/src/main/java/com/maxmind/geoip2/record/Postal.java
+++ b/src/main/java/com/maxmind/geoip2/record/Postal.java
@@ -1,18 +1,30 @@
package com.maxmind.geoip2.record;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.JsonSerializable;
/**
*
* Contains data for the postal record associated with an IP address.
*
+ *
+ * @param code The postal code of the location. Postal codes are not available for all
+ * countries. In some countries, this will only contain part of the postal
+ * code.
+ * @param confidence A value from 0-100 indicating MaxMind's confidence that the postal
+ * code is correct. This attribute is only available from the Insights
+ * web service and the GeoIP2 Enterprise database.
*/
-public final class Postal extends AbstractRecord {
+public record Postal(
+ @JsonProperty("code")
+ @MaxMindDbParameter(name = "code")
+ String code,
- private final String code;
- private final Integer confidence;
+ @JsonProperty("confidence")
+ @MaxMindDbParameter(name = "confidence")
+ Integer confidence
+) implements JsonSerializable {
/**
* Constructs a {@code Postal} record.
@@ -21,40 +33,25 @@ public Postal() {
this(null, null);
}
- /**
- * Constructs an instance of {@code Postal}.
- *
- * @param code The postal code of the location. Postal codes are not available
- * for all countries. In some countries, this will only contain part
- * of the postal code.
- * @param confidence A value from 0-100 indicating MaxMind's confidence that the
- * postal code is correct. This attribute is only available from the
- * Insights web service and the GeoIP2 Enterprise database.
- */
- @MaxMindDbConstructor
- public Postal(
- @JsonProperty("code") @MaxMindDbParameter(name = "code") String code,
- @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence
- ) {
- this.code = code;
- this.confidence = confidence;
- }
-
/**
* @return The postal code of the location. Postal codes are not available
* for all countries. In some countries, this will only contain part
* of the postal code.
+ * @deprecated Use {@link #code()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getCode() {
- return this.code;
+ return code();
}
/**
* @return A value from 0-100 indicating MaxMind's confidence that the
* postal code is correct. This attribute is only available from the
* Insights web service and the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #confidence()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public Integer getConfidence() {
- return this.confidence;
+ return confidence();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/RepresentedCountry.java b/src/main/java/com/maxmind/geoip2/record/RepresentedCountry.java
index 61c1a187..be9c0234 100644
--- a/src/main/java/com/maxmind/geoip2/record/RepresentedCountry.java
+++ b/src/main/java/com/maxmind/geoip2/record/RepresentedCountry.java
@@ -2,8 +2,8 @@
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.NamedRecord;
import java.util.List;
import java.util.Map;
@@ -18,53 +18,69 @@
*
*
* Do not use any of the country names as a database or map key. Use the value
- * returned by {@link #getGeoNameId} or {@link #getIsoCode} instead.
+ * returned by {@link #geonameId()} or {@link #isoCode()} instead.
*
+ *
+ * @param locales The locales to use for retrieving localized names.
+ * @param confidence A value from 0-100 indicating MaxMind's confidence that the
+ * country is correct. This attribute is only available from the
+ * Insights web service and the GeoIP2 Enterprise database.
+ * @param geonameId The GeoName ID for the country.
+ * @param isInEuropeanUnion This is true if the country is a member state of the
+ * European Union.
+ * @param isoCode The two-character ISO
+ * 3166-1 alpha code for the country.
+ * @param names A {@link Map} from locale codes to the name in that locale.
+ * @param type A string indicating the type of entity that is representing the
+ * country. Currently, we only return {@code military} but this could
+ * expand to include other types in the future.
*/
-public final class RepresentedCountry extends Country {
+public record RepresentedCountry(
+ @JacksonInject("locales")
+ @MaxMindDbParameter(name = "locales")
+ List locales,
- private final String type;
+ @JsonProperty("confidence")
+ @MaxMindDbParameter(name = "confidence")
+ Integer confidence,
+
+ @JsonProperty("geoname_id")
+ @MaxMindDbParameter(name = "geoname_id")
+ Long geonameId,
+
+ @JsonProperty("is_in_european_union")
+ @MaxMindDbParameter(name = "is_in_european_union", useDefault = true)
+ boolean isInEuropeanUnion,
+
+ @JsonProperty("iso_code")
+ @MaxMindDbParameter(name = "iso_code")
+ String isoCode,
+
+ @JsonProperty("names")
+ @MaxMindDbParameter(name = "names")
+ Map names,
+
+ @JsonProperty("type")
+ @MaxMindDbParameter(name = "type")
+ String type
+) implements NamedRecord {
/**
- * Constructs an instance of {@code RepresentedCountry} with no data.
+ * Compact canonical constructor that ensures immutability and handles null values.
*/
- public RepresentedCountry() {
- this(null, null, null, false, null, null, null);
+ public RepresentedCountry {
+ locales = locales != null ? List.copyOf(locales) : List.of();
+ names = names != null ? Map.copyOf(names) : Map.of();
}
/**
- * Constructs an instance of {@code RepresentedCountry}.
- *
- * @param locales The locales to use.
- * @param confidence This is a value from 0-100 indicating MaxMind's
- * confidence that the country is correct.
- * @param geoNameId This is a GeoName ID for the country.
- * @param isInEuropeanUnion This is true if the country is a member state of
- * the European Union.
- * @param isoCode This is a string up to three characters long contain the
- * country code.
- * @param names This is a map from locale codes to the names for the country
- * in that locale.
- * @param type This is a string indicating the type of entity that is
- * representing the country.
+ * Constructs an instance of {@code RepresentedCountry} with no data.
*/
- @MaxMindDbConstructor
- public RepresentedCountry(
- @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
- @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence,
- @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
- @JsonProperty("is_in_european_union") @MaxMindDbParameter(name = "is_in_european_union")
- Boolean isInEuropeanUnion,
- @JsonProperty("iso_code") @MaxMindDbParameter(name = "iso_code") String isoCode,
- @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names,
- @JsonProperty("type") @MaxMindDbParameter(name = "type") String type
- ) {
- super(locales, confidence, geoNameId, isInEuropeanUnion, isoCode,
- names);
- this.type = type;
+ public RepresentedCountry() {
+ this(null, null, null, false, null, null, null);
}
- /**
+ /**
* Constructs an instance of {@code RepresentedCountry}.
*
* @param country The {@code RepresentedCountry} object to copy.
@@ -76,12 +92,12 @@ public RepresentedCountry(
) {
this(
locales,
- country.getConfidence(),
- country.getGeoNameId(),
+ country.confidence(),
+ country.geonameId(),
country.isInEuropeanUnion(),
- country.getIsoCode(),
- country.getNames(),
- country.getType()
+ country.isoCode(),
+ country.names(),
+ country.type()
);
}
@@ -89,9 +105,63 @@ public RepresentedCountry(
* @return A string indicating the type of entity that is representing the
* country. Currently, we only return {@code military} but this could
* expand to include other types in the future.
+ * @deprecated Use {@link #type()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getType() {
- return this.type;
+ return type();
+ }
+
+ /**
+ * @return A value from 0-100 indicating MaxMind's confidence that the
+ * country is correct. This attribute is only available from the
+ * Insights web service and the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #confidence()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ public Integer getConfidence() {
+ return confidence();
+ }
+
+ /**
+ * @return The two-character ISO
+ * 3166-1 alpha code for the country.
+ * @deprecated Use {@link #isoCode()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("iso_code")
+ public String getIsoCode() {
+ return isoCode();
+ }
+
+ /**
+ * @return The GeoName ID for the country.
+ * @deprecated Use {@link #geonameId()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("geoname_id")
+ public Long getGeoNameId() {
+ return geonameId();
}
+ /**
+ * @return The name of the country based on the locales list.
+ * @deprecated Use {@link #name()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @com.fasterxml.jackson.annotation.JsonIgnore
+ public String getName() {
+ return name();
+ }
+
+ /**
+ * @return A {@link Map} from locale codes to the name in that locale.
+ * @deprecated Use {@link #names()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("names")
+ public Map getNames() {
+ return names();
+ }
}
diff --git a/src/main/java/com/maxmind/geoip2/record/Subdivision.java b/src/main/java/com/maxmind/geoip2/record/Subdivision.java
index 3a1cd4af..460fc6f1 100644
--- a/src/main/java/com/maxmind/geoip2/record/Subdivision.java
+++ b/src/main/java/com/maxmind/geoip2/record/Subdivision.java
@@ -2,8 +2,8 @@
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.maxmind.db.MaxMindDbConstructor;
import com.maxmind.db.MaxMindDbParameter;
+import com.maxmind.geoip2.NamedRecord;
import java.util.List;
import java.util.Map;
@@ -13,13 +13,48 @@
*
*
* Do not use any of the subdivision names as a database or map key. Use the
- * value returned by {@link #getGeoNameId} or {@link #getIsoCode} instead.
+ * value returned by {@link #geonameId()} or {@link #isoCode()} instead.
*
+ *
+ * @param locales The locales to use for retrieving localized names.
+ * @param confidence A value from 0-100 indicating MaxMind's confidence that the
+ * subdivision is correct. This attribute is only available from
+ * the Insights web service and the GeoIP2 Enterprise database.
+ * @param geonameId The GeoName ID for the subdivision.
+ * @param isoCode A string up to three characters long containing the subdivision
+ * portion of the ISO
+ * 3166-2 code.
+ * @param names A {@link Map} from locale codes to the name in that locale.
*/
-public final class Subdivision extends AbstractNamedRecord {
+public record Subdivision(
+ @JacksonInject("locales")
+ @MaxMindDbParameter(name = "locales")
+ List locales,
- private final Integer confidence;
- private final String isoCode;
+ @JsonProperty("confidence")
+ @MaxMindDbParameter(name = "confidence")
+ Integer confidence,
+
+ @JsonProperty("geoname_id")
+ @MaxMindDbParameter(name = "geoname_id")
+ Long geonameId,
+
+ @JsonProperty("iso_code")
+ @MaxMindDbParameter(name = "iso_code")
+ String isoCode,
+
+ @JsonProperty("names")
+ @MaxMindDbParameter(name = "names")
+ Map names
+) implements NamedRecord {
+
+ /**
+ * Compact canonical constructor that ensures immutability and handles null values.
+ */
+ public Subdivision {
+ locales = locales != null ? List.copyOf(locales) : List.of();
+ names = names != null ? Map.copyOf(names) : Map.of();
+ }
/**
* Constructs a {@code Subdivision} record.
@@ -28,29 +63,6 @@ public Subdivision() {
this(null, null, null, null, null);
}
- /**
- * Constructs an instance of {@code Subdivision}.
- *
- * @param locales The locales to use.
- * @param confidence This is a value from 0-100 indicating MaxMind's
- * confidence that the subdivision is correct.
- * @param geoNameId This is a GeoName ID for the subdivision.
- * @param isoCode This is a string up to three characters long contain the subdivision code.
- * @param names This is a map from locale codes to the names for the subdivision in that locale.
- */
- @MaxMindDbConstructor
- public Subdivision(
- @JacksonInject("locales") @MaxMindDbParameter(name = "locales") List locales,
- @JsonProperty("confidence") @MaxMindDbParameter(name = "confidence") Integer confidence,
- @JsonProperty("geoname_id") @MaxMindDbParameter(name = "geoname_id") Long geoNameId,
- @JsonProperty("iso_code") @MaxMindDbParameter(name = "iso_code") String isoCode,
- @JsonProperty("names") @MaxMindDbParameter(name = "names") Map names
- ) {
- super(locales, geoNameId, names);
- this.confidence = confidence;
- this.isoCode = isoCode;
- }
-
/**
* Constructs an instance of {@code Subdivision} with the specified parameters.
*
@@ -63,31 +75,65 @@ public Subdivision(
) {
this(
locales,
- subdivision.getConfidence(),
- subdivision.getGeoNameId(),
- subdivision.getIsoCode(),
- subdivision.getNames()
+ subdivision.confidence(),
+ subdivision.geonameId(),
+ subdivision.isoCode(),
+ subdivision.names()
);
}
/**
- * @return This is a value from 0-100 indicating MaxMind's confidence that
+ * @return A value from 0-100 indicating MaxMind's confidence that
* the subdivision is correct. This attribute is only available from
* the Insights web service and the GeoIP2 Enterprise database.
+ * @deprecated Use {@link #confidence()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("confidence")
public Integer getConfidence() {
- return this.confidence;
+ return confidence();
}
/**
- * @return This is a string up to three characters long contain the
+ * @return A string up to three characters long containing the
* subdivision portion of the ISO
- * 3166-2code.
+ * 3166-2 code.
+ * @deprecated Use {@link #isoCode()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("iso_code")
public String getIsoCode() {
- return this.isoCode;
+ return isoCode();
+ }
+
+ /**
+ * @return The GeoName ID for the subdivision.
+ * @deprecated Use {@link #geonameId()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("geoname_id")
+ public Long getGeoNameId() {
+ return geonameId();
+ }
+
+ /**
+ * @return The name of the subdivision based on the locales list.
+ * @deprecated Use {@link #name()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @com.fasterxml.jackson.annotation.JsonIgnore
+ public String getName() {
+ return name();
+ }
+
+ /**
+ * @return A {@link Map} from locale codes to the name in that locale.
+ * @deprecated Use {@link #names()} instead. This method will be removed in 6.0.0.
+ */
+ @Deprecated(since = "5.0.0", forRemoval = true)
+ @JsonProperty("names")
+ public Map getNames() {
+ return names();
}
}
diff --git a/src/main/java/com/maxmind/geoip2/record/Traits.java b/src/main/java/com/maxmind/geoip2/record/Traits.java
index 0330fcdf..2540b9d0 100644
--- a/src/main/java/com/maxmind/geoip2/record/Traits.java
+++ b/src/main/java/com/maxmind/geoip2/record/Traits.java
@@ -1,248 +1,174 @@
package com.maxmind.geoip2.record;
-import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.maxmind.db.MaxMindDbConstructor;
+import com.maxmind.db.MaxMindDbIpAddress;
+import com.maxmind.db.MaxMindDbNetwork;
import com.maxmind.db.MaxMindDbParameter;
import com.maxmind.db.Network;
+import com.maxmind.geoip2.JsonSerializable;
import com.maxmind.geoip2.NetworkDeserializer;
import com.maxmind.geoip2.model.ConnectionTypeResponse.ConnectionType;
+import java.net.InetAddress;
/**
* Contains data for the traits record associated with an IP address.
+ *
+ * @param autonomousSystemNumber The autonomous system number associated with the IP address.
+ * This is only available from the City Plus and Insights web
+ * services and the Enterprise database.
+ * @param autonomousSystemOrganization The organization associated with the registered autonomous system number for the IP address. This is
+ * only available from the City Plus and Insights web services
+ * and the Enterprise database.
+ * @param connectionType The connection type of the IP address. This is only available from the
+ * City Plus and Insights web services and the Enterprise database.
+ * @param domain The second level domain associated with the IP address. This will be something
+ * like "example.com" or "example.co.uk", not "foo.example.com". This is only
+ * available from the City Plus and Insights web services and the Enterprise
+ * database.
+ * @param ipAddress The IP address that the data in the model is for. If you performed a "me"
+ * lookup against the web service, this will be the externally routable IP
+ * address for the system the code is running on. If the system is behind a
+ * NAT, this may differ from the IP address locally assigned to it.
+ * @param isAnonymous This is true if the IP address belongs to any sort of anonymous network.
+ * @param isAnonymousVpn This is true if the IP address belongs to an anonymous VPN system.
+ * @param isAnycast This is true if the IP address is an anycast address.
+ * @param isHostingProvider This is true if the IP address belongs to a hosting provider.
+ * @param isLegitimateProxy This is true if the IP address belongs to a legitimate proxy.
+ * @param isPublicProxy This is true if the IP address belongs to a public proxy.
+ * @param isResidentialProxy This is true if the IP address is on a suspected anonymizing network
+ * and belongs to a residential ISP.
+ * @param isTorExitNode This is true if the IP address is a Tor exit node.
+ * @param isp The name of the ISP associated with the IP address. This is only available from
+ * the City Plus and Insights web services and the Enterprise database.
+ * @param mobileCountryCode The
+ * mobile country code (MCC) associated with the IP address and ISP.
+ * This is available from the City Plus and Insights web services and
+ * the Enterprise database.
+ * @param mobileNetworkCode The
+ * mobile network code (MNC) associated with the IP address and ISP.
+ * This is available from the City Plus and Insights web services and
+ * the Enterprise database.
+ * @param network The network associated with the record. In particular, this is the largest
+ * network where all the fields besides IP address have the same value.
+ * @param organization The name of the organization associated with the IP address. This is only
+ * available from the City Plus and Insights web services and the Enterprise
+ * database.
+ * @param userType The user type associated with the IP address. This can be one of the following
+ * values: business, cafe, cellular, college, consumer_privacy_network,
+ * content_delivery_network, dialup, government, hosting, library, military,
+ * residential, router, school, search_engine_spider, traveler. This is only
+ * available from the Insights web service and the Enterprise database.
+ * @param userCount The estimated number of users sharing the IP address/network during the past
+ * 24 hours. For IPv4, the count is for the individual IP address. For IPv6, the
+ * count is for the /64 network. This is only available from the Insights web
+ * service.
+ * @param staticIpScore The static IP score of the IP address. This is an indicator of how static
+ * or dynamic an IP address is. This is only available from the Insights web
+ * service.
*/
-public final class Traits extends AbstractRecord {
-
- private final Long autonomousSystemNumber;
- private final String autonomousSystemOrganization;
- private final ConnectionType connectionType;
- private final String domain;
- private final String ipAddress;
- private final boolean isAnonymous;
- private final boolean isAnonymousVpn;
- private final boolean isAnycast;
- private final boolean isHostingProvider;
- private final boolean isLegitimateProxy;
- private final boolean isPublicProxy;
- private final boolean isResidentialProxy;
- private final boolean isTorExitNode;
- private final String isp;
- private final String mobileCountryCode;
- private final String mobileNetworkCode;
- private final Network network;
- private final String organization;
- private final String userType;
- private final Integer userCount;
- private final Double staticIpScore;
+public record Traits(
+ @JsonProperty("autonomous_system_number")
+ @MaxMindDbParameter(name = "autonomous_system_number")
+ Long autonomousSystemNumber,
- /**
- * Constructs an instance of {@code Traits}.
- */
- public Traits() {
- this(null, null, null, null,
- null, false, false, false, false,
- false, false, false, false, null,
- null, null, null, null, null, null, null);
- }
+ @JsonProperty("autonomous_system_organization")
+ @MaxMindDbParameter(name = "autonomous_system_organization")
+ String autonomousSystemOrganization,
- /**
- * Constructs an instance of {@code Traits}.
- *
- * @param ipAddress the IP address
- * @param network the network
- */
- public Traits(String ipAddress, Network network) {
- this(null, null, null, null,
- ipAddress, false, false, false, false,
- false, false, false, false, null,
- null, null, network, null, null, null, null);
- }
+ @JsonProperty("connection_type")
+ @MaxMindDbParameter(name = "connection_type")
+ ConnectionType connectionType,
- /**
- * Constructs an instance of {@code Traits}.
- *
- * @param autonomousSystemNumber the autonomous system number
- * @param autonomousSystemOrganization the autonomous system organization
- * @param connectionType the connection type
- * @param domain the domain
- * @param ipAddress the IP address
- * @param isAnonymous the anonymous flag
- * @param isAnonymousVpn the anonymous VPN flag
- * @param isAnycast the anycast flag
- * @param isHostingProvider the hosting provider flag
- * @param isLegitimateProxy the legitimate proxy flag
- * @param isPublicProxy the public proxy flag
- * @param isResidentialProxy the residential proxy flag
- * @param isTorExitNode the Tor exit node flag
- * @param isp the ISP
- * @param mobileCountryCode the mobile country code
- * @param mobileNetworkCode the mobile network code
- * @param network the network
- * @param organization the organization
- * @param userType the user type
- * @param userCount the user count
- * @param staticIpScore the static IP score
- */
- public Traits(
- @JsonProperty("autonomous_system_number") Long autonomousSystemNumber,
- @JsonProperty("autonomous_system_organization") String autonomousSystemOrganization,
- @JsonProperty("connection_type") ConnectionType connectionType,
- @JsonProperty("domain") String domain,
- @JsonProperty("ip_address") String ipAddress,
- @JsonProperty("is_anonymous") boolean isAnonymous,
- @JsonProperty("is_anonymous_vpn") boolean isAnonymousVpn,
- @JsonProperty("is_anycast") boolean isAnycast,
- @JsonProperty("is_hosting_provider") boolean isHostingProvider,
- @JsonProperty("is_legitimate_proxy") boolean isLegitimateProxy,
- @JsonProperty("is_public_proxy") boolean isPublicProxy,
- @JsonProperty("is_residential_proxy") boolean isResidentialProxy,
- @JsonProperty("is_tor_exit_node") boolean isTorExitNode,
- @JsonProperty("isp") String isp,
- @JsonProperty("mobile_country_code") String mobileCountryCode,
- @JsonProperty("mobile_network_code") String mobileNetworkCode,
- @JsonProperty("network")
- @JsonDeserialize(using = NetworkDeserializer.class) Network network,
- @JsonProperty("organization") String organization,
- @JsonProperty("user_type") String userType,
- @JsonProperty("user_count") Integer userCount,
- @JsonProperty("static_ip_score") Double staticIpScore
- ) {
- this.autonomousSystemNumber = autonomousSystemNumber;
- this.autonomousSystemOrganization = autonomousSystemOrganization;
- this.connectionType = connectionType;
- this.domain = domain;
- this.ipAddress = ipAddress;
- this.isAnonymous = isAnonymous;
- this.isAnonymousVpn = isAnonymousVpn;
- this.isAnycast = isAnycast;
- this.isHostingProvider = isHostingProvider;
- this.isLegitimateProxy = isLegitimateProxy;
- this.isPublicProxy = isPublicProxy;
- this.isResidentialProxy = isResidentialProxy;
- this.isTorExitNode = isTorExitNode;
- this.isp = isp;
- this.mobileCountryCode = mobileCountryCode;
- this.mobileNetworkCode = mobileNetworkCode;
- this.network = network;
- this.organization = organization;
- this.userType = userType;
- this.userCount = userCount;
- this.staticIpScore = staticIpScore;
- }
+ @JsonProperty("domain")
+ @MaxMindDbParameter(name = "domain")
+ String domain,
- /**
- * Constructs an instance of {@code Traits}.
- *
- * @param autonomousSystemNumber the autonomous system number
- * @param autonomousSystemOrganization the autonomous system organization
- * @param connectionType the connection type
- * @param domain the domain
- * @param ipAddress the IP address
- * @param isAnonymous the anonymous flag
- * @param isAnonymousVpn the anonymous VPN flag
- * @param isAnycast the anycast flag
- * @param isHostingProvider the hosting provider flag
- * @param isLegitimateProxy the legitimate proxy flag
- * @param isPublicProxy the public proxy flag
- * @param isResidentialProxy the residential proxy flag
- * @param isTorExitNode the Tor exit node flag
- * @param isp the ISP
- * @param mobileCountryCode the mobile country code
- * @param mobileNetworkCode the mobile network code
- * @param network the network
- * @param organization the organization
- * @param userType the user type
- * @param userCount the user count
- * @param staticIpScore the static IP score
- */
- @MaxMindDbConstructor
- public Traits(
- @MaxMindDbParameter(name = "autonomous_system_number") Long autonomousSystemNumber,
- @MaxMindDbParameter(name = "autonomous_system_organization")
- String autonomousSystemOrganization,
- @MaxMindDbParameter(name = "connection_type") String connectionType,
- @MaxMindDbParameter(name = "domain") String domain,
- @MaxMindDbParameter(name = "ip_address") String ipAddress,
- @MaxMindDbParameter(name = "is_anonymous") Boolean isAnonymous,
- @MaxMindDbParameter(name = "is_anonymous_vpn") Boolean isAnonymousVpn,
- @MaxMindDbParameter(name = "is_anycast") Boolean isAnycast,
- @MaxMindDbParameter(name = "is_hosting_provider") Boolean isHostingProvider,
- @MaxMindDbParameter(name = "is_legitimate_proxy") Boolean isLegitimateProxy,
- @MaxMindDbParameter(name = "is_public_proxy") Boolean isPublicProxy,
- @MaxMindDbParameter(name = "is_residential_proxy") Boolean isResidentialProxy,
- @MaxMindDbParameter(name = "is_tor_exit_node") Boolean isTorExitNode,
- @MaxMindDbParameter(name = "isp") String isp,
- @MaxMindDbParameter(name = "mobile_country_code") String mobileCountryCode,
- @MaxMindDbParameter(name = "mobile_network_code") String mobileNetworkCode,
- @MaxMindDbParameter(name = "network") Network network,
- @MaxMindDbParameter(name = "organization") String organization,
- @MaxMindDbParameter(name = "user_type") String userType,
- @MaxMindDbParameter(name = "user_count") Integer userCount,
- @MaxMindDbParameter(name = "static_ip_score") Double staticIpScore
- ) {
- this.autonomousSystemNumber = autonomousSystemNumber;
- this.autonomousSystemOrganization = autonomousSystemOrganization;
- this.connectionType = ConnectionType.fromString(connectionType);
- this.domain = domain;
- this.ipAddress = ipAddress;
- this.isAnonymous = isAnonymous != null ? isAnonymous : false;
- this.isAnonymousVpn = isAnonymousVpn != null ? isAnonymousVpn : false;
- this.isAnycast = isAnycast != null ? isAnycast : false;
- this.isHostingProvider = isHostingProvider != null ? isHostingProvider : false;
- this.isLegitimateProxy = isLegitimateProxy != null ? isLegitimateProxy : false;
- this.isPublicProxy = isPublicProxy != null ? isPublicProxy : false;
- this.isResidentialProxy = isResidentialProxy != null ? isResidentialProxy : false;
- this.isTorExitNode = isTorExitNode != null ? isTorExitNode : false;
- this.isp = isp;
- this.mobileCountryCode = mobileCountryCode;
- this.mobileNetworkCode = mobileNetworkCode;
- this.network = network;
- this.organization = organization;
- this.userType = userType;
- this.userCount = userCount;
- this.staticIpScore = staticIpScore;
- }
+ @JsonProperty("ip_address")
+ @MaxMindDbIpAddress
+ InetAddress ipAddress,
+ @JsonProperty("is_anonymous")
+ @MaxMindDbParameter(name = "is_anonymous", useDefault = true)
+ boolean isAnonymous,
+ @JsonProperty("is_anonymous_vpn")
+ @MaxMindDbParameter(name = "is_anonymous_vpn", useDefault = true)
+ boolean isAnonymousVpn,
+
+ @JsonProperty("is_anycast")
+ @MaxMindDbParameter(name = "is_anycast", useDefault = true)
+ boolean isAnycast,
+
+ @JsonProperty("is_hosting_provider")
+ @MaxMindDbParameter(name = "is_hosting_provider", useDefault = true)
+ boolean isHostingProvider,
+
+ @JsonProperty("is_legitimate_proxy")
+ @MaxMindDbParameter(name = "is_legitimate_proxy", useDefault = true)
+ boolean isLegitimateProxy,
+
+ @JsonProperty("is_public_proxy")
+ @MaxMindDbParameter(name = "is_public_proxy", useDefault = true)
+ boolean isPublicProxy,
+
+ @JsonProperty("is_residential_proxy")
+ @MaxMindDbParameter(name = "is_residential_proxy", useDefault = true)
+ boolean isResidentialProxy,
+
+ @JsonProperty("is_tor_exit_node")
+ @MaxMindDbParameter(name = "is_tor_exit_node", useDefault = true)
+ boolean isTorExitNode,
+
+ @JsonProperty("isp")
+ @MaxMindDbParameter(name = "isp")
+ String isp,
+
+ @JsonProperty("mobile_country_code")
+ @MaxMindDbParameter(name = "mobile_country_code")
+ String mobileCountryCode,
+
+ @JsonProperty("mobile_network_code")
+ @MaxMindDbParameter(name = "mobile_network_code")
+ String mobileNetworkCode,
+
+ @JsonProperty("network")
+ @JsonDeserialize(using = NetworkDeserializer.class)
+ @JsonSerialize(using = ToStringSerializer.class)
+ @MaxMindDbNetwork
+ Network network,
+
+ @JsonProperty("organization")
+ @MaxMindDbParameter(name = "organization")
+ String organization,
+
+ @JsonProperty("user_type")
+ @MaxMindDbParameter(name = "user_type")
+ String userType,
+
+ @JsonProperty("user_count")
+ @MaxMindDbParameter(name = "user_count")
+ Integer userCount,
+
+ @JsonProperty("static_ip_score")
+ @MaxMindDbParameter(name = "static_ip_score")
+ Double staticIpScore
+) implements JsonSerializable {
/**
- * Constructs an instance of {@code Traits}.
- *
- * @param traits the traits
- * @param ipAddress the IP address
- * @param network the network
+ * Constructs an instance of {@code Traits}.
*/
- public Traits(
- Traits traits,
- String ipAddress,
- Network network
- ) {
- this(
- traits.getAutonomousSystemNumber(),
- traits.getAutonomousSystemOrganization(),
- traits.getConnectionType(),
- traits.getDomain(),
- ipAddress,
- traits.isAnonymous(),
- traits.isAnonymousVpn(),
- traits.isAnycast(),
- traits.isHostingProvider(),
- traits.isLegitimateProxy(),
- traits.isPublicProxy(),
- traits.isResidentialProxy(),
- traits.isTorExitNode(),
- traits.getIsp(),
- traits.getMobileCountryCode(),
- traits.getMobileNetworkCode(),
- network,
- traits.getOrganization(),
- traits.getUserType(),
- traits.getUserCount(),
- traits.getStaticIpScore()
- );
+ public Traits() {
+ this(null, null, (ConnectionType) null, null,
+ null, false, false, false, false,
+ false, false, false, false, null,
+ null, null, null, null, null, null, null);
}
/**
@@ -251,10 +177,13 @@ public Traits(
* >autonomous system number associated with the IP address. This
* is only available from the City Plus and Insights web services and
* the Enterprise database.
+ * @deprecated Use {@link #autonomousSystemNumber()} instead. This method will be
+ * removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("autonomous_system_number")
public Long getAutonomousSystemNumber() {
- return this.autonomousSystemNumber;
+ return autonomousSystemNumber();
}
/**
@@ -263,30 +192,37 @@ public Long getAutonomousSystemNumber() {
* >autonomous system number for the IP address. This is only
* available from the City Plus and Insights web services and the
* Enterprise database.
+ * @deprecated Use {@link #autonomousSystemOrganization()} instead. This method will be
+ * removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("autonomous_system_organization")
public String getAutonomousSystemOrganization() {
- return this.autonomousSystemOrganization;
+ return autonomousSystemOrganization();
}
/**
* @return The connection type of the IP address. This is only
* available from the City Plus and Insights web services and the
* Enterprise database.
+ * @deprecated Use {@link #connectionType()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("connection_type")
public ConnectionType getConnectionType() {
- return this.connectionType;
+ return connectionType();
}
/**
* @return The static IP score of the IP address. This is an indicator of
* how static or dynamic an IP address is. This is only available from
* the Insights web service.
+ * @deprecated Use {@link #staticIpScore()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("static_ip_score")
public Double getStaticIpScore() {
- return this.staticIpScore;
+ return staticIpScore();
}
/**
@@ -294,10 +230,12 @@ public Double getStaticIpScore() {
* during the past 24 hours. For IPv4, the count is for the individual
* IP address. For IPv6, the count is for the /64 network. This is only
* available from the Insights web service.
+ * @deprecated Use {@link #userCount()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("user_count")
public Integer getUserCount() {
- return this.userCount;
+ return userCount();
}
/**
@@ -305,10 +243,12 @@ public Integer getUserCount() {
* will be something like "example.com" or "example.co.uk", not
* "foo.example.com". This is only available from the City Plus and
* Insights web services and the Enterprise database.
+ * @deprecated Use {@link #domain()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
public String getDomain() {
- return this.domain;
+ return domain();
}
/**
@@ -317,100 +257,23 @@ public String getDomain() {
* externally routable IP address for the system the code is running
* on. If the system is behind a NAT, this may differ from the IP
* address locally assigned to it.
+ * @deprecated Use {@link #ipAddress()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("ip_address")
public String getIpAddress() {
- return this.ipAddress;
+ return ipAddress().getHostAddress();
}
/**
* @return The name of the ISP associated with the IP address. This
* is only available from the City Plus and Insights web services and
* the Enterprise database.
+ * @deprecated Use {@link #isp()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
public String getIsp() {
- return this.isp;
- }
-
- /**
- * @return This is true if the IP address belongs to any sort of anonymous
- * network. This is only available from the Insights web service.
- */
- @JsonProperty("is_anonymous")
- public boolean isAnonymous() {
- return this.isAnonymous;
- }
-
-
- /**
- * @return This is true if the IP address is registered to an anonymous
- * VPN provider. If a VPN provider does not register subnets under names
- * associated with them, we will likely only flag their IP ranges using
- * isHostingProvider. This is only available from the Insights web
- * service.
- */
- @JsonProperty("is_anonymous_vpn")
- public boolean isAnonymousVpn() {
- return this.isAnonymousVpn;
- }
-
- /**
- * @return This is true if the IP address belongs to an anycast network.
- * This is not available from GeoLite databases or web services.
- */
- @JsonProperty("is_anycast")
- public boolean isAnycast() {
- return this.isAnycast;
- }
-
- /**
- * @return This is true if the IP address belongs to a hosting or
- * VPN provider (see description of isAnonymousVpn). This is only
- * available from the Insights web service.
- */
- @JsonProperty("is_hosting_provider")
- public boolean isHostingProvider() {
- return this.isHostingProvider;
- }
-
- /**
- * @return This is true if MaxMind believes this IP address to be a
- * legitimate proxy, such as an internal VPN used by a corporation. This is
- * only available in the Enterprise database.
- */
- @JsonProperty("is_legitimate_proxy")
- public boolean isLegitimateProxy() {
- return this.isLegitimateProxy;
- }
-
- /**
- * @return This is true if the IP address belongs to a public proxy.
- * This is only available from the Insights web service.
- */
- @JsonProperty("is_public_proxy")
- public boolean isPublicProxy() {
- return this.isPublicProxy;
- }
-
- /**
- * @return This is true if the IP address is on a suspected anonymizing
- * network and belongs to a residential ISP. This is only available from
- * the Insights web service.
- */
- @JsonProperty("is_residential_proxy")
- public boolean isResidentialProxy() {
- return this.isResidentialProxy;
- }
-
-
- /**
- * @return This is true if the IP address belongs to a Tor exit node.
- * This is only available from the Insights web service.
- */
- @JsonProperty("is_tor_exit_node")
- public boolean isTorExitNode() {
- return this.isTorExitNode;
+ return isp();
}
/**
@@ -418,10 +281,12 @@ public boolean isTorExitNode() {
* mobile country code (MCC) associated with the IP address and ISP.
* This is available from the City Plus and Insights web services and the
* Enterprise database.
+ * @deprecated Use {@link #mobileCountryCode()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("mobile_country_code")
public String getMobileCountryCode() {
- return this.mobileCountryCode;
+ return mobileCountryCode();
}
/**
@@ -429,31 +294,37 @@ public String getMobileCountryCode() {
* mobile network code (MNC) associated with the IP address and ISP.
* This is available from the City Plus and Insights web services and the
* Enterprise database.
+ * @deprecated Use {@link #mobileNetworkCode()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("mobile_network_code")
public String getMobileNetworkCode() {
- return this.mobileNetworkCode;
+ return mobileNetworkCode();
}
/**
* @return The network associated with the record. In particular, this is
* the largest network where all the fields besides IP address have the
* same value.
+ * @deprecated Use {@link #network()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
@JsonSerialize(using = ToStringSerializer.class)
public Network getNetwork() {
- return this.network;
+ return network();
}
/**
* @return The name of the organization associated with the IP address.
* This is only available from the City Plus and Insights web services and
* the Enterprise database.
+ * @deprecated Use {@link #organization()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty
public String getOrganization() {
- return this.organization;
+ return organization();
}
/**
@@ -483,9 +354,11 @@ public String getOrganization() {
* This is only available from the Insights web service and the Enterprise
* database.
*
+ * @deprecated Use {@link #userType()} instead. This method will be removed in 6.0.0.
*/
+ @Deprecated(since = "5.0.0", forRemoval = true)
@JsonProperty("user_type")
public String getUserType() {
- return this.userType;
+ return userType();
}
}
diff --git a/src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java b/src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
index e70b3e05..b92e1a1c 100644
--- a/src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
+++ b/src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
@@ -63,7 +63,7 @@ public void testDefaultLocaleURL() throws Exception {
private void testDefaultLocale(DatabaseReader reader) throws IOException,
GeoIp2Exception {
CityResponse city = reader.city(InetAddress.getByName("81.2.69.160"));
- assertEquals("London", city.getCity().getName());
+ assertEquals("London", city.city().name());
}
@Test
@@ -72,8 +72,8 @@ public void testIsInEuropeanUnion() throws Exception {
.build()
) {
CityResponse city = reader.city(InetAddress.getByName("89.160.20.128"));
- assertTrue(city.getCountry().isInEuropeanUnion());
- assertTrue(city.getRegisteredCountry().isInEuropeanUnion());
+ assertTrue(city.country().isInEuropeanUnion());
+ assertTrue(city.registeredCountry().isInEuropeanUnion());
}
}
@@ -100,7 +100,7 @@ public void testLocaleListURL() throws Exception {
private void testLocaleList(DatabaseReader reader) throws IOException,
GeoIp2Exception {
CityResponse city = reader.city(InetAddress.getByName("81.2.69.160"));
- assertEquals("Лондон", city.getCity().getName());
+ assertEquals("Лондон", city.city().name());
}
@Test
@@ -124,15 +124,15 @@ public void testMemoryModeURL() throws Exception {
private void testMemoryMode(DatabaseReader reader) throws IOException,
GeoIp2Exception {
CityResponse city = reader.city(InetAddress.getByName("81.2.69.160"));
- assertEquals("London", city.getCity().getName());
- assertEquals(100, city.getLocation().getAccuracyRadius().longValue());
+ assertEquals("London", city.city().name());
+ assertEquals(100, city.location().accuracyRadius().longValue());
}
@Test
public void metadata() throws IOException {
DatabaseReader reader = new DatabaseReader.Builder(this.geoipFile)
.fileMode(Reader.FileMode.MEMORY).build();
- assertEquals("GeoIP2-City", reader.getMetadata().getDatabaseType());
+ assertEquals("GeoIP2-City", reader.metadata().databaseType());
}
@Test
@@ -156,8 +156,8 @@ public void hasIpAddressURL() throws Exception {
private void hasIpInfo(DatabaseReader reader) throws IOException,
GeoIp2Exception {
CityResponse cio = reader.city(InetAddress.getByName("81.2.69.160"));
- assertEquals("81.2.69.160", cio.getTraits().getIpAddress());
- assertEquals("81.2.69.160/27", cio.getTraits().getNetwork().toString());
+ assertEquals("81.2.69.160", cio.traits().ipAddress().getHostAddress());
+ assertEquals("81.2.69.160/27", cio.traits().network().toString());
}
@Test
@@ -220,8 +220,8 @@ public void testAnonymousIp() throws Exception {
assertFalse(response.isPublicProxy());
assertFalse(response.isResidentialProxy());
assertFalse(response.isTorExitNode());
- assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
- assertEquals("1.2.0.0/16", response.getNetwork().toString());
+ assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
+ assertEquals("1.2.0.0/16", response.network().toString());
AnonymousIpResponse tryResponse = reader.tryAnonymousIp(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
@@ -235,17 +235,17 @@ public void testAnonymousPlus() throws Exception {
) {
InetAddress ipAddress = InetAddress.getByName("1.2.0.1");
AnonymousPlusResponse response = reader.anonymousPlus(ipAddress);
- assertEquals(30, response.getAnonymizerConfidence());
+ assertEquals(30, response.anonymizerConfidence());
assertTrue(response.isAnonymous());
assertTrue(response.isAnonymousVpn());
assertFalse(response.isHostingProvider());
assertFalse(response.isPublicProxy());
assertFalse(response.isResidentialProxy());
assertFalse(response.isTorExitNode());
- assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
- assertEquals("1.2.0.1/32", response.getNetwork().toString());
- assertEquals("2025-04-14", response.getNetworkLastSeen().toString());
- assertEquals("foo", response.getProviderName());
+ assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
+ assertEquals("1.2.0.1/32", response.network().toString());
+ assertEquals("2025-04-14", response.networkLastSeen().toString());
+ assertEquals("foo", response.providerName());
AnonymousPlusResponse tryResponse = reader.tryAnonymousPlus(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
@@ -270,11 +270,11 @@ public void testAsn() throws Exception {
) {
InetAddress ipAddress = InetAddress.getByName("1.128.0.0");
AsnResponse response = reader.asn(ipAddress);
- assertEquals(1221, response.getAutonomousSystemNumber().intValue());
+ assertEquals(1221, response.autonomousSystemNumber().intValue());
assertEquals("Telstra Pty Ltd",
- response.getAutonomousSystemOrganization());
- assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
- assertEquals("1.128.0.0/11", response.getNetwork().toString());
+ response.autonomousSystemOrganization());
+ assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
+ assertEquals("1.128.0.0/11", response.network().toString());
AsnResponse tryResponse = reader.tryAsn(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
@@ -289,18 +289,18 @@ public void testCity() throws Exception {
InetAddress ipAddress = InetAddress.getByName("81.2.69.192");
CityResponse response = reader.city(ipAddress);
- assertEquals(2635167, response.getCountry().getGeoNameId().intValue());
- assertEquals(100, response.getLocation().getAccuracyRadius().intValue());
- assertFalse(response.getTraits().isLegitimateProxy());
- assertEquals(ipAddress.getHostAddress(), response.getTraits().getIpAddress());
- assertEquals("81.2.69.192/28", response.getTraits().getNetwork().toString());
+ assertEquals(2635167, response.country().geonameId().intValue());
+ assertEquals(100, response.location().accuracyRadius().intValue());
+ assertFalse(response.traits().isLegitimateProxy());
+ assertEquals(ipAddress.getHostAddress(), response.traits().ipAddress().getHostAddress());
+ assertEquals("81.2.69.192/28", response.traits().network().toString());
CityResponse tryResponse = reader.tryCity(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
// This IP has is_anycast
response = reader.city(InetAddress.getByName("214.1.1.0"));
- assertTrue(response.getTraits().isAnycast());
+ assertTrue(response.traits().isAnycast());
// Test that the methods can be called on DB without
// an exception
@@ -317,9 +317,9 @@ public void testConnectionType() throws Exception {
ConnectionTypeResponse response = reader.connectionType(ipAddress);
- assertEquals(ConnectionType.CELLULAR, response.getConnectionType());
- assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
- assertEquals("1.0.1.0/24", response.getNetwork().toString());
+ assertEquals(ConnectionType.CELLULAR, response.connectionType());
+ assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
+ assertEquals("1.0.1.0/24", response.network().toString());
ConnectionTypeResponse tryResponse = reader.tryConnectionType(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
@@ -334,18 +334,18 @@ public void testCountry() throws Exception {
InetAddress ipAddress = InetAddress.getByName("74.209.24.0");
CountryResponse response = reader.country(ipAddress);
- assertEquals("NA", response.getContinent().getCode());
- assertEquals(6252001, response.getCountry().getGeoNameId().intValue());
- assertEquals(6252001, response.getRegisteredCountry().getGeoNameId().intValue());
- assertEquals(ipAddress.getHostAddress(), response.getTraits().getIpAddress());
- assertEquals("74.209.16.0/20", response.getTraits().getNetwork().toString());
+ assertEquals("NA", response.continent().code());
+ assertEquals(6252001, response.country().geonameId().intValue());
+ assertEquals(6252001, response.registeredCountry().geonameId().intValue());
+ assertEquals(ipAddress.getHostAddress(), response.traits().ipAddress().getHostAddress());
+ assertEquals("74.209.16.0/20", response.traits().network().toString());
CountryResponse tryResponse = reader.tryCountry(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
// This IP has is_anycast
response = reader.country(InetAddress.getByName("214.1.1.0"));
- assertTrue(response.getTraits().isAnycast());
+ assertTrue(response.traits().isAnycast());
}
}
@@ -356,9 +356,9 @@ public void testDomain() throws Exception {
) {
InetAddress ipAddress = InetAddress.getByName("1.2.0.0");
DomainResponse response = reader.domain(ipAddress);
- assertEquals("maxmind.com", response.getDomain());
- assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
- assertEquals("1.2.0.0/16", response.getNetwork().toString());
+ assertEquals("maxmind.com", response.domain());
+ assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
+ assertEquals("1.2.0.0/16", response.network().toString());
DomainResponse tryResponse = reader.tryDomain(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
@@ -373,26 +373,26 @@ public void testEnterprise() throws Exception {
InetAddress ipAddress = InetAddress.getByName("74.209.24.0");
EnterpriseResponse response = reader.enterprise(ipAddress);
- assertEquals(11, response.getCity().getConfidence().intValue());
- assertEquals(99, response.getCountry().getConfidence().intValue());
- assertEquals(6252001, response.getCountry().getGeoNameId().intValue());
- assertEquals(27, response.getLocation().getAccuracyRadius().intValue());
- assertEquals(ConnectionType.CABLE_DSL, response.getTraits().getConnectionType());
- assertTrue(response.getTraits().isLegitimateProxy());
- assertEquals(ipAddress.getHostAddress(), response.getTraits().getIpAddress());
- assertEquals("74.209.16.0/20", response.getTraits().getNetwork().toString());
+ assertEquals(11, response.city().confidence().intValue());
+ assertEquals(99, response.country().confidence().intValue());
+ assertEquals(6252001, response.country().geonameId().intValue());
+ assertEquals(27, response.location().accuracyRadius().intValue());
+ assertEquals(ConnectionType.CABLE_DSL, response.traits().connectionType());
+ assertTrue(response.traits().isLegitimateProxy());
+ assertEquals(ipAddress.getHostAddress(), response.traits().ipAddress().getHostAddress());
+ assertEquals("74.209.16.0/20", response.traits().network().toString());
EnterpriseResponse tryResponse = reader.tryEnterprise(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
ipAddress = InetAddress.getByName("149.101.100.0");
response = reader.enterprise(ipAddress);
- assertEquals("310", response.getTraits().getMobileCountryCode());
- assertEquals("004", response.getTraits().getMobileNetworkCode());
+ assertEquals("310", response.traits().mobileCountryCode());
+ assertEquals("004", response.traits().mobileNetworkCode());
// This IP has is_anycast
response = reader.enterprise(InetAddress.getByName("214.1.1.0"));
- assertTrue(response.getTraits().isAnycast());
+ assertTrue(response.traits().isAnycast());
// Test that the city and country methods can be called without
// an exception
@@ -408,22 +408,22 @@ public void testIsp() throws Exception {
) {
InetAddress ipAddress = InetAddress.getByName("1.128.0.0");
IspResponse response = reader.isp(ipAddress);
- assertEquals(1221, response.getAutonomousSystemNumber().intValue());
+ assertEquals(1221, response.autonomousSystemNumber().intValue());
assertEquals("Telstra Pty Ltd",
- response.getAutonomousSystemOrganization());
- assertEquals("Telstra Internet", response.getIsp());
- assertEquals("Telstra Internet", response.getOrganization());
+ response.autonomousSystemOrganization());
+ assertEquals("Telstra Internet", response.isp());
+ assertEquals("Telstra Internet", response.organization());
- assertEquals(ipAddress.getHostAddress(), response.getIpAddress());
- assertEquals("1.128.0.0/11", response.getNetwork().toString());
+ assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
+ assertEquals("1.128.0.0/11", response.network().toString());
IspResponse tryResponse = reader.tryIsp(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
ipAddress = InetAddress.getByName("149.101.100.0");
response = reader.isp(ipAddress);
- assertEquals("310", response.getMobileCountryCode());
- assertEquals("004", response.getMobileNetworkCode());
+ assertEquals("310", response.mobileCountryCode());
+ assertEquals("004", response.mobileNetworkCode());
}
}
diff --git a/src/test/java/com/maxmind/geoip2/NetworkDeserializerTest.java b/src/test/java/com/maxmind/geoip2/NetworkDeserializerTest.java
index 60acf26d..35b2d57c 100644
--- a/src/test/java/com/maxmind/geoip2/NetworkDeserializerTest.java
+++ b/src/test/java/com/maxmind/geoip2/NetworkDeserializerTest.java
@@ -23,8 +23,8 @@ private static Network parse(String jsonString) throws IOException {
}
private static void assertNetwork(Network n, String addr, int prefix) throws Exception {
assertNotNull(n);
- assertEquals(InetAddress.getByName(addr), n.getNetworkAddress());
- assertEquals(prefix, n.getPrefixLength());
+ assertEquals(InetAddress.getByName(addr), n.networkAddress());
+ assertEquals(prefix, n.prefixLength());
}
@Test
diff --git a/src/test/java/com/maxmind/geoip2/WebServiceClientTest.java b/src/test/java/com/maxmind/geoip2/WebServiceClientTest.java
index 03500381..cd5c2af0 100644
--- a/src/test/java/com/maxmind/geoip2/WebServiceClientTest.java
+++ b/src/test/java/com/maxmind/geoip2/WebServiceClientTest.java
@@ -25,7 +25,6 @@
import com.maxmind.geoip2.exception.OutOfQueriesException;
import com.maxmind.geoip2.exception.PermissionRequiredException;
import com.maxmind.geoip2.model.InsightsResponse;
-import com.maxmind.geoip2.record.AbstractNamedRecord;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Continent;
import com.maxmind.geoip2.record.Country;
@@ -71,7 +70,6 @@ public void test200WithInvalidJson() throws Exception {
assertEquals("Received a 200 response but could not decode it as JSON", ex.getMessage());
}
- @SuppressWarnings("deprecation")
@Test
public void test200WithDefaultValues() throws Exception {
WebServiceClient client = createSuccessClient("insights", "1.2.3.13",
@@ -81,93 +79,98 @@ public void test200WithDefaultValues() throws Exception {
.getByName("1.2.3.13"));
assertThat(insights.toString(),
- CoreMatchers.startsWith("com.maxmind.geoip2.model.InsightsResponse [ {"));
+ CoreMatchers.startsWith("InsightsResponse["));
- City city = insights.getCity();
+ City city = insights.city();
assertNotNull(city);
- assertNull(city.getConfidence());
+ assertNull(city.confidence());
- Continent continent = insights.getContinent();
+ Continent continent = insights.continent();
assertNotNull(continent);
- assertNull(continent.getCode());
+ assertNull(continent.code());
- Country country = insights.getCountry();
+ Country country = insights.country();
assertNotNull(country);
- Location location = insights.getLocation();
+ Location location = insights.location();
assertNotNull(location);
- assertNull(location.getAccuracyRadius());
- assertNull(location.getLatitude());
- assertNull(location.getLongitude());
- assertNull(location.getTimeZone());
+ assertNull(location.accuracyRadius());
+ assertNull(location.latitude());
+ assertNull(location.longitude());
+ assertNull(location.timeZone());
assertThat(location.toString(),
- CoreMatchers.equalTo("com.maxmind.geoip2.record.Location [ {} ]"));
+ CoreMatchers.startsWith("Location["));
- MaxMind maxmind = insights.getMaxMind();
+ MaxMind maxmind = insights.maxmind();
assertNotNull(maxmind);
- assertNull(maxmind.getQueriesRemaining());
+ assertNull(maxmind.queriesRemaining());
- assertNotNull(insights.getPostal());
+ assertNotNull(insights.postal());
- Country registeredCountry = insights.getRegisteredCountry();
+ Country registeredCountry = insights.registeredCountry();
assertNotNull(registeredCountry);
RepresentedCountry representedCountry = insights
- .getRepresentedCountry();
+ .representedCountry();
assertNotNull(representedCountry);
- assertNull(representedCountry.getType());
+ assertNull(representedCountry.type());
- List subdivisions = insights.getSubdivisions();
+ List subdivisions = insights.subdivisions();
assertNotNull(subdivisions);
assertTrue(subdivisions.isEmpty());
- Subdivision subdiv = insights.getMostSpecificSubdivision();
+ Subdivision subdiv = insights.mostSpecificSubdivision();
assertNotNull(subdiv);
- assertNull(subdiv.getIsoCode());
- assertNull(subdiv.getConfidence());
+ assertNull(subdiv.isoCode());
+ assertNull(subdiv.confidence());
- Subdivision leastSpecificSubdiv = insights.getLeastSpecificSubdivision();
+ Subdivision leastSpecificSubdiv = insights.leastSpecificSubdivision();
assertNotNull(leastSpecificSubdiv);
- assertNull(leastSpecificSubdiv.getIsoCode());
- assertNull(leastSpecificSubdiv.getConfidence());
+ assertNull(leastSpecificSubdiv.isoCode());
+ assertNull(leastSpecificSubdiv.confidence());
- Traits traits = insights.getTraits();
+ Traits traits = insights.traits();
assertNotNull(traits);
- assertNull(traits.getAutonomousSystemNumber());
- assertNull(traits.getAutonomousSystemOrganization());
- assertNull(traits.getConnectionType());
- assertNull(traits.getDomain());
- assertEquals("1.2.3.13", traits.getIpAddress());
- assertEquals("1.2.3.0/24", traits.getNetwork().toString());
- assertNull(traits.getIsp());
- assertNull(traits.getOrganization());
- assertNull(traits.getUserType());
- assertNull(traits.getStaticIpScore());
- assertNull(traits.getUserCount());
+ assertNull(traits.autonomousSystemNumber());
+ assertNull(traits.autonomousSystemOrganization());
+ assertNull(traits.connectionType());
+ assertNull(traits.domain());
+ assertEquals("1.2.3.13", traits.ipAddress().getHostAddress());
+ assertEquals("1.2.3.0/24", traits.network().toString());
+ assertNull(traits.isp());
+ assertNull(traits.organization());
+ assertNull(traits.userType());
+ assertNull(traits.staticIpScore());
+ assertNull(traits.userCount());
assertFalse(traits.isAnycast());
- for (Country c : new Country[] {country, registeredCountry,
- representedCountry}) {
- assertNull(c.getConfidence());
- assertNull(c.getIsoCode());
+ for (Country c : new Country[] {country, registeredCountry}) {
+ assertNull(c.confidence());
+ assertNull(c.isoCode());
assertFalse(c.isInEuropeanUnion());
}
- for (AbstractNamedRecord r : new AbstractNamedRecord[] {city,
+ // Check RepresentedCountry separately since it's no longer a Country
+ assertNull(representedCountry.confidence());
+ assertNull(representedCountry.isoCode());
+ assertFalse(representedCountry.isInEuropeanUnion());
+
+ for (NamedRecord r : new NamedRecord[] {city,
continent, subdiv}) {
- assertNull(r.getGeoNameId());
- assertNull(r.getName());
- assertTrue(r.getNames().isEmpty());
- assertEquals(r.getClass().getName() + " [ {} ]", r.toString());
+ assertNull(r.geonameId());
+ assertNull(r.name());
+ assertTrue(r.names().isEmpty());
+ // Records have their own toString format
+ assertNotNull(r.toString());
}
- for (AbstractNamedRecord r : new AbstractNamedRecord[] {country,
+ for (NamedRecord r : new NamedRecord[] {country,
registeredCountry, representedCountry}) {
- assertNull(r.getGeoNameId());
- assertNull(r.getName());
- assertTrue(r.getNames().isEmpty());
- assertEquals(r.getClass().getName() +
- " [ {\"is_in_european_union\":false} ]", r.toString());
+ assertNull(r.geonameId());
+ assertNull(r.name());
+ assertTrue(r.names().isEmpty());
+ // Records have their own toString format
+ assertNotNull(r.toString());
}
}
@@ -176,7 +179,7 @@ public void test200OnInsightsAsMe() throws Exception {
WebServiceClient client = createSuccessClient("insights", "me",
"{\"traits\":{\"ip_address\":\"24.24.24.24\"}}");
assertEquals("24.24.24.24",
- client.insights().getTraits().getIpAddress());
+ client.insights().traits().ipAddress().getHostAddress());
}
@Test
@@ -184,7 +187,7 @@ public void test200OnCityAsMe() throws Exception {
WebServiceClient client = createSuccessClient("city", "me",
"{\"traits\":{\"ip_address\":\"24.24.24.24\"}}");
assertEquals("24.24.24.24",
- client.city().getTraits().getIpAddress());
+ client.city().traits().ipAddress().getHostAddress());
}
@Test
@@ -192,7 +195,7 @@ public void test200OnCountryAsMe() throws Exception {
WebServiceClient client = createSuccessClient("country", "me",
"{\"traits\":{\"ip_address\":\"24.24.24.24\"}}");
assertEquals("24.24.24.24",
- client.country().getTraits().getIpAddress());
+ client.country().traits().ipAddress().getHostAddress());
}
@Test
diff --git a/src/test/java/com/maxmind/geoip2/matchers/CodeMatcher.java b/src/test/java/com/maxmind/geoip2/matchers/CodeMatcher.java
index 9b1cb00f..bef6fe21 100644
--- a/src/test/java/com/maxmind/geoip2/matchers/CodeMatcher.java
+++ b/src/test/java/com/maxmind/geoip2/matchers/CodeMatcher.java
@@ -19,7 +19,7 @@ private CodeMatcher(String expectedErrorCode) {
@Override
protected boolean matchesSafely(final InvalidRequestException exception) {
- this.foundErrorCode = exception.getCode();
+ this.foundErrorCode = exception.code();
return this.foundErrorCode.equalsIgnoreCase(this.expectedErrorCode);
}
diff --git a/src/test/java/com/maxmind/geoip2/matchers/HttpStatusMatcher.java b/src/test/java/com/maxmind/geoip2/matchers/HttpStatusMatcher.java
index 9704e309..8d192138 100644
--- a/src/test/java/com/maxmind/geoip2/matchers/HttpStatusMatcher.java
+++ b/src/test/java/com/maxmind/geoip2/matchers/HttpStatusMatcher.java
@@ -19,7 +19,7 @@ private HttpStatusMatcher(int expectedStatusCode) {
@Override
protected boolean matchesSafely(final HttpException exception) {
- this.foundStatusCode = exception.getHttpStatus();
+ this.foundStatusCode = exception.httpStatus();
return this.foundStatusCode == this.expectedStatusCode;
}
diff --git a/src/test/java/com/maxmind/geoip2/model/CityResponseTest.java b/src/test/java/com/maxmind/geoip2/model/CityResponseTest.java
index 5b080e73..a9dce2a6 100644
--- a/src/test/java/com/maxmind/geoip2/model/CityResponseTest.java
+++ b/src/test/java/com/maxmind/geoip2/model/CityResponseTest.java
@@ -55,17 +55,17 @@ public void testNames() throws Exception {
CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
assertEquals(
"北美洲",
- city.getContinent().getName(),
- "country.getContinent().getName() does not return 北美洲"
+ city.continent().name(),
+ "country.continent().name() does not return 北美洲"
);
assertEquals(
"美国",
- city.getCountry().getName(),
- "country.getCountry().getName() does not return 美国"
+ city.country().name(),
+ "country.country().name() does not return 美国"
);
assertEquals(
- city.getCountry()
- .getName(), city.getCountry().getName(),
+ city.country()
+ .name(), city.country().name(),
"toString() returns getName()"
);
}
@@ -82,8 +82,8 @@ public void russianFallback() throws Exception {
CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
assertEquals(
"объединяет государства",
- city.getCountry().getName(),
- "country.getCountry().getName() does not return объединяет государства"
+ city.country().name(),
+ "country.country().name() does not return объединяет государства"
);
}
@@ -99,7 +99,7 @@ public void testFallback() throws Exception {
CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
assertEquals(
"North America",
- city.getContinent().getName(),
+ city.continent().name(),
"en is returned when pt is missing"
);
@@ -116,7 +116,7 @@ public void noFallback() throws Exception {
CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
assertNull(
- city.getContinent().getName(),
+ city.continent().name(),
"null is returned when locale is not available"
);
}
@@ -132,7 +132,7 @@ public void noLocale() throws Exception {
CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
assertEquals(
"North America",
- city.getContinent().getName(),
+ city.continent().name(),
"en is returned when no locales are specified"
);
@@ -148,7 +148,7 @@ public void testMissing() throws Exception {
.locales(Collections.singletonList("en")).build();
CityResponse city = client.city(InetAddress.getByName("1.1.1.2"));
- assertNotNull(city.getCity());
- assertNull(city.getCity().getName(), "null is returned when names object is missing");
+ assertNotNull(city.city());
+ assertNull(city.city().name(), "null is returned when names object is missing");
}
}
diff --git a/src/test/java/com/maxmind/geoip2/model/CountryResponseTest.java b/src/test/java/com/maxmind/geoip2/model/CountryResponseTest.java
index 9535f077..d0a7c415 100644
--- a/src/test/java/com/maxmind/geoip2/model/CountryResponseTest.java
+++ b/src/test/java/com/maxmind/geoip2/model/CountryResponseTest.java
@@ -52,97 +52,97 @@ public void createClient() throws IOException, GeoIp2Exception,
public void testContinent() {
assertEquals(
"NA",
- this.country.getContinent().getCode(),
- "country.getContinent().getCode() does not return NA"
+ this.country.continent().code(),
+ "country.continent().code() does not return NA"
);
assertEquals(
42,
- this.country.getContinent().getGeoNameId(),
- "country.getContinent().getGeoNameId() does not return 42"
+ this.country.continent().geonameId(),
+ "country.continent().geonameId() does not return 42"
);
assertEquals(
"North America",
- this.country.getContinent().getName(),
- "country.getContinent().getName() does not return North America"
+ this.country.continent().name(),
+ "country.continent().name() does not return North America"
);
}
@Test
public void testCountry() {
assertFalse(
- this.country.getCountry().isInEuropeanUnion(),
- "country.getCountry().isInEuropeanUnion() does not return false"
+ this.country.country().isInEuropeanUnion(),
+ "country.country().isInEuropeanUnion() does not return false"
);
assertEquals(
- this.country.getCountry().getIsoCode(),
+ this.country.country().isoCode(),
"US",
- "country.getCountry().getCode() does not return US"
+ "country.country().code() does not return US"
);
assertEquals(
1,
- (long) this.country.getCountry().getGeoNameId(),
- "country.getCountry().getGeoNameId() does not return 1"
+ (long) this.country.country().geonameId(),
+ "country.country().geonameId() does not return 1"
);
assertEquals(
Integer.valueOf(56),
- this.country.getCountry().getConfidence(),
- "country.getCountry().getConfidence() does not return 56"
+ this.country.country().confidence(),
+ "country.country().confidence() does not return 56"
);
assertEquals(
"United States",
- this.country.getCountry().getName(),
- "country.getCountry().getName(\"en\") does not return United States"
+ this.country.country().name(),
+ "country.country().name(\"en\") does not return United States"
);
}
@Test
public void testRegisteredCountry() {
assertFalse(
- this.country.getRegisteredCountry().isInEuropeanUnion(),
- "country.getRegisteredCountry().isInEuropeanUnion() does not return false"
+ this.country.registeredCountry().isInEuropeanUnion(),
+ "country.registeredCountry().isInEuropeanUnion() does not return false"
);
assertEquals(
"CA",
- this.country.getRegisteredCountry().getIsoCode(),
- "country.getRegisteredCountry().getIsoCode() does not return CA"
+ this.country.registeredCountry().isoCode(),
+ "country.registeredCountry().isoCode() does not return CA"
);
assertEquals(
2,
- (long) this.country.getRegisteredCountry().getGeoNameId(),
- "country.getRegisteredCountry().getGeoNameId() does not return 2"
+ (long) this.country.registeredCountry().geonameId(),
+ "country.registeredCountry().geonameId() does not return 2"
);
assertEquals(
"Canada",
- this.country.getRegisteredCountry().getName(),
- "country.getRegisteredCountry().getName(\"en\") does not return United States"
+ this.country.registeredCountry().name(),
+ "country.registeredCountry().name(\"en\") does not return United States"
);
}
@Test
public void testRepresentedCountry() {
assertTrue(
- this.country.getRepresentedCountry().isInEuropeanUnion(),
- "country.getRepresentedCountry().isInEuropeanUnion() does not return true"
+ this.country.representedCountry().isInEuropeanUnion(),
+ "country.representedCountry().isInEuropeanUnion() does not return true"
);
assertEquals(
"GB",
- this.country.getRepresentedCountry().getIsoCode(),
- "country.getRepresentedCountry().getCode() does not return GB"
+ this.country.representedCountry().isoCode(),
+ "country.representedCountry().code() does not return GB"
);
assertEquals(
4,
- (long) this.country.getRepresentedCountry().getGeoNameId(),
- "country.getRepresentedCountry().getGeoNameId() does not return 4"
+ (long) this.country.representedCountry().geonameId(),
+ "country.representedCountry().geonameId() does not return 4"
);
assertEquals(
"United Kingdom",
- this.country.getRepresentedCountry().getName(),
- "country.getRepresentedCountry().getName(\"en\") does not return United Kingdom"
+ this.country.representedCountry().name(),
+ "country.representedCountry().name(\"en\") does not return United Kingdom"
);
assertEquals(
"military",
- this.country.getRepresentedCountry().getType(),
- "country.getRepresentedCountry().getType() does not return military"
+ this.country.representedCountry().type(),
+ "country.representedCountry().type() does not return military"
);
}
@@ -151,8 +151,8 @@ public void testTraits() {
assertEquals(
"1.2.3.4",
- this.country.getTraits().getIpAddress(),
- "country.getTraits().getIpAddress does not return 1.2.3.4"
+ this.country.traits().ipAddress().getHostAddress(),
+ "country.traits().getIpAddress does not return 1.2.3.4"
);
}
diff --git a/src/test/java/com/maxmind/geoip2/model/InsightsResponseTest.java b/src/test/java/com/maxmind/geoip2/model/InsightsResponseTest.java
index 34dab71e..ae76aed2 100644
--- a/src/test/java/com/maxmind/geoip2/model/InsightsResponseTest.java
+++ b/src/test/java/com/maxmind/geoip2/model/InsightsResponseTest.java
@@ -64,7 +64,7 @@ public void createClient() throws IOException, GeoIp2Exception,
@Test
public void testSubdivisionsList() {
- List subdivisionsList = this.insights.getSubdivisions();
+ List subdivisionsList = this.insights.subdivisions();
assertNotNull(subdivisionsList, "city.getSubdivisionsList returns null");
if (subdivisionsList.isEmpty()) {
fail("subdivisionsList is empty");
@@ -72,18 +72,18 @@ public void testSubdivisionsList() {
Subdivision subdivision = subdivisionsList.get(0);
assertEquals(
Integer.valueOf(88),
- subdivision.getConfidence(),
- "subdivision.getConfidence() does not return 88"
+ subdivision.confidence(),
+ "subdivision.confidence() does not return 88"
);
assertEquals(
574635,
- subdivision.getGeoNameId().intValue(),
- "subdivision.getGeoNameId() does not return 574635"
+ subdivision.geonameId().intValue(),
+ "subdivision.geonameId() does not return 574635"
);
assertEquals(
"MN",
- subdivision.getIsoCode(),
- "subdivision.getCode() does not return MN"
+ subdivision.isoCode(),
+ "subdivision.code() does not return MN"
);
}
@@ -91,7 +91,7 @@ public void testSubdivisionsList() {
public void mostSpecificSubdivision() {
assertEquals(
"TT",
- this.insights.getMostSpecificSubdivision().getIsoCode(),
+ this.insights.mostSpecificSubdivision().isoCode(),
"Most specific subdivision returns last subdivision"
);
}
@@ -100,43 +100,42 @@ public void mostSpecificSubdivision() {
public void leastSpecificSubdivision() {
assertEquals(
"MN",
- this.insights.getLeastSpecificSubdivision().getIsoCode(),
+ this.insights.leastSpecificSubdivision().isoCode(),
"Most specific subdivision returns first subdivision"
);
}
- @SuppressWarnings("deprecation")
@Test
public void testTraits() {
- Traits traits = this.insights.getTraits();
+ Traits traits = this.insights.traits();
- assertNotNull(traits, "city.getTraits() returns null");
+ assertNotNull(traits, "city.traits() returns null");
assertEquals(
Long.valueOf(1234),
- traits.getAutonomousSystemNumber(),
- "traits.getAutonomousSystemNumber() does not return 1234"
+ traits.autonomousSystemNumber(),
+ "traits.autonomousSystemNumber() does not return 1234"
);
assertEquals(
"AS Organization",
- traits.getAutonomousSystemOrganization(),
- "traits.getAutonomousSystemOrganization() does not return AS Organization"
+ traits.autonomousSystemOrganization(),
+ "traits.autonomousSystemOrganization() does not return AS Organization"
);
assertEquals(
ConnectionType.CABLE_DSL,
- traits.getConnectionType(),
- "traits.getConnectionType() does not return Cable/DSL"
+ traits.connectionType(),
+ "traits.connectionType() does not return Cable/DSL"
);
assertEquals(
"example.com",
- traits.getDomain(),
- "traits.getDomain() does not return example.com"
+ traits.domain(),
+ "traits.domain() does not return example.com"
);
assertEquals(
"1.2.3.4",
- traits.getIpAddress(),
- "traits.getIpAddress() does not return 1.2.3.4"
+ traits.ipAddress().getHostAddress(),
+ "traits.ipAddress() does not return 1.2.3.4"
);
assertTrue(traits.isAnonymous(), "traits.isAnonymous() returns true");
assertTrue(traits.isAnonymousVpn(), "traits.isAnonymousVpn() returns true");
@@ -146,83 +145,82 @@ public void testTraits() {
assertTrue(traits.isTorExitNode(), "traits.isTorExitNode() returns true");
assertEquals(
"Comcast",
- traits.getIsp(),
- "traits.getIsp() does not return Comcast"
+ traits.isp(),
+ "traits.isp() does not return Comcast"
);
assertEquals(
"Blorg",
- traits.getOrganization(),
- "traits.getOrganization() does not return Blorg"
+ traits.organization(),
+ "traits.organization() does not return Blorg"
);
assertEquals(
"college",
- traits.getUserType(),
- "traits.getUserType() does not return userType"
+ traits.userType(),
+ "traits.userType() does not return userType"
);
assertEquals(
Double.valueOf(1.3),
- traits.getStaticIpScore(),
- "traits.getStaticIpScore() does not return 1.3"
+ traits.staticIpScore(),
+ "traits.staticIpScore() does not return 1.3"
);
assertEquals(
Integer.valueOf(2),
- traits.getUserCount(),
- "traits.getUserCount() does not return 2"
+ traits.userCount(),
+ "traits.userCount() does not return 2"
);
}
- @SuppressWarnings("deprecation")
@Test
public void testLocation() {
- Location location = this.insights.getLocation();
+ Location location = this.insights.location();
- assertNotNull(location, "city.getLocation() returns null");
+ assertNotNull(location, "city.location() returns null");
assertEquals(
Integer.valueOf(24626),
- location.getAverageIncome(),
- "location.getAverageIncome() does not return 24626"
+ location.averageIncome(),
+ "location.averageIncome() does not return 24626"
);
assertEquals(
Integer.valueOf(1500),
- location.getAccuracyRadius(),
- "location.getAccuracyRadius() does not return 1500"
+ location.accuracyRadius(),
+ "location.accuracyRadius() does not return 1500"
);
- double latitude = location.getLatitude();
+ double latitude = location.latitude();
assertEquals(
44.98,
latitude,
0.1,
- "location.getLatitude() does not return 44.98"
+ "location.latitude() does not return 44.98"
);
- double longitude = location.getLongitude();
+ double longitude = location.longitude();
assertEquals(
93.2636,
longitude,
0.1,
- "location.getLongitude() does not return 93.2636"
+ "location.longitude() does not return 93.2636"
);
assertEquals(
Integer.valueOf(1341),
- location.getPopulationDensity(),
- "location.getPopulationDensity() does not return 1341"
+ location.populationDensity(),
+ "location.populationDensity() does not return 1341"
);
assertEquals(
"America/Chicago",
- location.getTimeZone(),
- "location.getTimeZone() does not return America/Chicago"
+ location.timeZone(),
+ "location.timeZone() does not return America/Chicago"
);
}
@Test
public void testMaxMind() {
- MaxMind maxmind = this.insights.getMaxMind();
+ MaxMind maxmind = this.insights.maxmind();
assertEquals(
11, maxmind
- .getQueriesRemaining().intValue(),
+ .queriesRemaining().intValue(),
"Correct number of queries remaining"
);
}
@@ -230,34 +228,34 @@ public void testMaxMind() {
@Test
public void testPostal() {
- Postal postal = this.insights.getPostal();
+ Postal postal = this.insights.postal();
assertEquals(
"55401",
- postal.getCode(),
- "postal.getCode() does not return 55401"
+ postal.code(),
+ "postal.code() does not return 55401"
);
assertEquals(
Integer.valueOf(33),
- postal.getConfidence(),
- "postal.getConfidence() does not return 33"
+ postal.confidence(),
+ "postal.confidence() does not return 33"
);
}
@Test
public void testRepresentedCountry() {
assertNotNull(
- this.insights.getRepresentedCountry(),
- "city.getRepresentedCountry() returns null"
+ this.insights.representedCountry(),
+ "city.representedCountry() returns null"
);
assertEquals(
"C",
- this.insights.getRepresentedCountry().getType(),
- "city.getRepresentedCountry().getType() does not return C"
+ this.insights.representedCountry().type(),
+ "city.representedCountry().type() does not return C"
);
assertTrue(
- this.insights.getRepresentedCountry().isInEuropeanUnion(),
- "city.getRepresentedCountry().isInEuropeanUnion() does not return true"
+ this.insights.representedCountry().isInEuropeanUnion(),
+ "city.representedCountry().isInEuropeanUnion() does not return true"
);
}
@@ -276,11 +274,11 @@ public void testIsInEuropeanUnion() throws IOException, GeoIp2Exception {
InetAddress.getByName("1.1.1.2"));
assertTrue(
- insights.getCountry().isInEuropeanUnion(),
+ insights.country().isInEuropeanUnion(),
"getCountry().isInEuropeanUnion() does not return true"
);
assertTrue(
- insights.getRegisteredCountry().isInEuropeanUnion(),
+ insights.registeredCountry().isInEuropeanUnion(),
"getRegisteredCountry().() isInEuropeanUnion = does not return true"
);
}
diff --git a/src/test/java/com/maxmind/geoip2/model/JsonTest.java b/src/test/java/com/maxmind/geoip2/model/JsonTest.java
index 1a59fce6..73aab8da 100644
--- a/src/test/java/com/maxmind/geoip2/model/JsonTest.java
+++ b/src/test/java/com/maxmind/geoip2/model/JsonTest.java
@@ -329,11 +329,12 @@ public void testIspSerialization() throws Exception {
testRoundTrip(IspResponse.class, json);
}
- protected void testRoundTrip
+ protected void testRoundTrip
(Class cls, String json)
throws IOException {
JsonMapper mapper = JsonMapper.builder()
.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)
+ .addModule(new com.maxmind.geoip2.InetAddressModule())
.build();
InjectableValues inject = new InjectableValues.Std().addValue(
"locales", Collections.singletonList("en"));