forked from I2P_Developers/i2p.i2p
Modify GeoIP2-java
to remove the dependency on the large com.fasterxml.jackson.databind JSON package, and use POJOs instead. Add main() for testing
This commit is contained in:
@ -1,12 +1,7 @@
|
||||
package com.maxmind.geoip2;
|
||||
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.maxmind.db.*;
|
||||
import com.maxmind.db.Reader.FileMode;
|
||||
import com.maxmind.geoip2.exception.AddressNotFoundException;
|
||||
import com.maxmind.geoip2.exception.GeoIp2Exception;
|
||||
import com.maxmind.geoip2.model.*;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
@ -15,8 +10,11 @@ import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Modified and simplified for I2P
|
||||
*
|
||||
* <p>
|
||||
* The class {@code DatabaseReader} provides a reader for the GeoIP2 database
|
||||
* format.
|
||||
@ -50,13 +48,13 @@ import java.util.List;
|
||||
* {@code com.maxmind.db.CHMCache}. Using this cache, lookup performance is
|
||||
* significantly improved at the cost of a small (~2MB) memory overhead.
|
||||
* </p>
|
||||
*
|
||||
* @since 0.9.38
|
||||
*/
|
||||
public class DatabaseReader implements DatabaseProvider, Closeable {
|
||||
public class DatabaseReader implements Closeable {
|
||||
|
||||
private final Reader reader;
|
||||
|
||||
private final ObjectMapper om;
|
||||
|
||||
private final List<String> locales;
|
||||
|
||||
private DatabaseReader(Builder builder) throws IOException {
|
||||
@ -70,12 +68,6 @@ public class DatabaseReader implements DatabaseProvider, Closeable {
|
||||
throw new IllegalArgumentException(
|
||||
"Unsupported Builder configuration: expected either File or URL");
|
||||
}
|
||||
this.om = new ObjectMapper();
|
||||
this.om.configure(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS, false);
|
||||
this.om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
|
||||
false);
|
||||
this.om.configure(
|
||||
DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
|
||||
this.locales = builder.locales;
|
||||
}
|
||||
|
||||
@ -162,13 +154,31 @@ public class DatabaseReader implements DatabaseProvider, Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map containing:
|
||||
*
|
||||
*<ul><li>continent: Map containing:
|
||||
* <ul><li>code: String
|
||||
* <li>names: Map of lang to translated name
|
||||
* <li>geoname_id: Long
|
||||
* </ul>
|
||||
*<ul><li>country: Map containing:
|
||||
* <ul><li>iso_code: String
|
||||
* <li>names: Map of lang to translated name
|
||||
* <li>geoname_id: Long
|
||||
* </ul>
|
||||
*<ul><li>registered_country: Map containing:
|
||||
* <ul><li>iso_code: String
|
||||
* <li>names: Map of lang to translated name
|
||||
* <li>geoname_id: Long
|
||||
* </ul>
|
||||
*</ul>
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return A <T> object with the data for the IP address
|
||||
* @return A Map with the data for the IP address
|
||||
* @throws IOException if there is an error opening or reading from the file.
|
||||
* @throws AddressNotFoundException if the IP address is not in our database
|
||||
*/
|
||||
private <T> T get(InetAddress ipAddress, Class<T> cls,
|
||||
String type) throws IOException, AddressNotFoundException {
|
||||
private Object get(InetAddress ipAddress,
|
||||
String type) throws IOException {
|
||||
|
||||
String databaseType = this.getMetadata().getDatabaseType();
|
||||
if (!databaseType.contains(type)) {
|
||||
@ -179,27 +189,7 @@ public class DatabaseReader implements DatabaseProvider, Closeable {
|
||||
+ " database using the " + caller + " method");
|
||||
}
|
||||
|
||||
ObjectNode node = jsonNodeToObjectNode(reader.get(ipAddress));
|
||||
|
||||
// We throw the same exception as the web service when an IP is not in
|
||||
// the database
|
||||
if (node == null) {
|
||||
throw new AddressNotFoundException("The address "
|
||||
+ ipAddress.getHostAddress() + " is not in the database.");
|
||||
}
|
||||
|
||||
InjectableValues inject = new JsonInjector(locales, ipAddress.getHostAddress());
|
||||
|
||||
return this.om.reader(inject).treeToValue(node, cls);
|
||||
}
|
||||
|
||||
private ObjectNode jsonNodeToObjectNode(JsonNode node)
|
||||
throws InvalidDatabaseException {
|
||||
if (node == null || node instanceof ObjectNode) {
|
||||
return (ObjectNode) node;
|
||||
}
|
||||
throw new InvalidDatabaseException(
|
||||
"Unexpected data type returned. The GeoIP2 database may be corrupt.");
|
||||
return reader.get(ipAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,103 +211,21 @@ public class DatabaseReader implements DatabaseProvider, Closeable {
|
||||
this.reader.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CountryResponse country(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this.get(ipAddress, CountryResponse.class, "Country");
|
||||
}
|
||||
public String country(String ipAddress) throws IOException {
|
||||
InetAddress ia = InetAddress.getByName(ipAddress);
|
||||
Object o = get(ia, "Country");
|
||||
if (!(o instanceof Map))
|
||||
return null;
|
||||
Map m = (Map) o;
|
||||
o = m.get("country");
|
||||
if (!(o instanceof Map))
|
||||
return null;
|
||||
m = (Map) o;
|
||||
o = m.get("iso_code");
|
||||
if (!(o instanceof String))
|
||||
return null;
|
||||
return (String) o;
|
||||
|
||||
@Override
|
||||
public CityResponse city(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this.get(ipAddress, CityResponse.class, "City");
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an IP address in a GeoIP2 Anonymous IP.
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return a AnonymousIpResponse for the requested IP address.
|
||||
* @throws GeoIp2Exception if there is an error looking up the IP
|
||||
* @throws IOException if there is an IO error
|
||||
*/
|
||||
@Override
|
||||
public AnonymousIpResponse anonymousIp(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this.get(ipAddress, AnonymousIpResponse.class, "GeoIP2-Anonymous-IP");
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an IP address in a GeoLite2 ASN database.
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return an AsnResponse for the requested IP address.
|
||||
* @throws GeoIp2Exception if there is an error looking up the IP
|
||||
* @throws IOException if there is an IO error
|
||||
*/
|
||||
@Override
|
||||
public AsnResponse asn(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this.get(ipAddress, AsnResponse.class, "GeoLite2-ASN");
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an IP address in a GeoIP2 Connection Type database.
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return a ConnectTypeResponse for the requested IP address.
|
||||
* @throws GeoIp2Exception if there is an error looking up the IP
|
||||
* @throws IOException if there is an IO error
|
||||
*/
|
||||
@Override
|
||||
public ConnectionTypeResponse connectionType(InetAddress ipAddress)
|
||||
throws IOException, GeoIp2Exception {
|
||||
return this.get(ipAddress, ConnectionTypeResponse.class,
|
||||
"GeoIP2-Connection-Type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an IP address in a GeoIP2 Domain database.
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return a DomainResponse for the requested IP address.
|
||||
* @throws GeoIp2Exception if there is an error looking up the IP
|
||||
* @throws IOException if there is an IO error
|
||||
*/
|
||||
@Override
|
||||
public DomainResponse domain(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this
|
||||
.get(ipAddress, DomainResponse.class, "GeoIP2-Domain");
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an IP address in a GeoIP2 Enterprise database.
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return an EnterpriseResponse for the requested IP address.
|
||||
* @throws GeoIp2Exception if there is an error looking up the IP
|
||||
* @throws IOException if there is an IO error
|
||||
*/
|
||||
@Override
|
||||
public EnterpriseResponse enterprise(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this.get(ipAddress, EnterpriseResponse.class, "Enterprise");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look up an IP address in a GeoIP2 ISP database.
|
||||
*
|
||||
* @param ipAddress IPv4 or IPv6 address to lookup.
|
||||
* @return an IspResponse for the requested IP address.
|
||||
* @throws GeoIp2Exception if there is an error looking up the IP
|
||||
* @throws IOException if there is an IO error
|
||||
*/
|
||||
@Override
|
||||
public IspResponse isp(InetAddress ipAddress) throws IOException,
|
||||
GeoIp2Exception {
|
||||
return this.get(ipAddress, IspResponse.class, "GeoIP2-ISP");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,4 +234,18 @@ public class DatabaseReader implements DatabaseProvider, Closeable {
|
||||
public Metadata getMetadata() {
|
||||
return this.reader.getMetadata();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length != 2) {
|
||||
System.err.println("Usage: DatabaseReader geoip2-file.mmdb ip");
|
||||
System.exit(1);
|
||||
}
|
||||
File f = new File(args[0]);
|
||||
Builder b = new Builder(f);
|
||||
b.withCache(new CHMCache(256));
|
||||
DatabaseReader r = b.build();
|
||||
System.out.println("Database Metadata: " + r.getMetadata());
|
||||
String c = r.country(args[1]);
|
||||
System.out.println("IP: " + args[1] + " country: " + c);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user