package com.maxmind.geoip2; import com.maxmind.db.*; import com.maxmind.db.Reader.FileMode; import java.io.Closeable; import java.io.File; import java.io.IOException; 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 * *
* The class {@code DatabaseReader} provides a reader for the GeoIP2 database * format. *
** To use the database API, you must create a new {@code DatabaseReader} using * the {@code DatabaseReader.Builder}. You must provide the {@code Builder} * constructor either an {@code InputStream} or {@code File} for your GeoIP2 * database. You may also specify the {@code fileMode} and the {@code locales} * fallback order using the methods on the {@code Builder} object. After you * have created the {@code DatabaseReader}, you may then call the appropriate * method (e.g., {@code city}) for your database, passing it the IP address * you want to look up. *
** If the lookup succeeds, the method call will return a response class for * the GeoIP2 lookup. The class in turn contains multiple record classes, * each of which represents part of the data returned by the database. *
** We recommend reusing the {@code DatabaseReader} object rather than creating * a new one for each lookup. The creation of this object is relatively * expensive as it must read in metadata for the file. It is safe to share the * object across threads. *
** The database API supports pluggable caching (by default, no caching is * performed). A simple implementation is provided by * {@code com.maxmind.db.CHMCache}. Using this cache, lookup performance is * significantly improved at the cost of a small (~2MB) memory overhead. *
* * @since 0.9.38 */ public class DatabaseReader implements Closeable { private final Reader reader; private final List* Constructs a Builder for the {@code DatabaseReader}. The file passed to * it must be a valid GeoIP2 database file. *
** {@code Builder} creates instances of {@code DatabaseReader} * from values set by the methods. *
** Only the values set in the {@code Builder} constructor are required. *
*/ public static final class Builder { final File database; final InputStream stream; List* Closes the database. *
** If you are using {@code FileMode.MEMORY_MAPPED}, this will * not unmap the underlying file due to a limitation in Java's * {@code MappedByteBuffer}. It will however set the reference to * the buffer to {@code null}, allowing the garbage collector to * collect it. *
* * @throws IOException if an I/O error occurs. */ @Override public void close() throws IOException { this.reader.close(); } 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; } /** * @return the metadata for the open MaxMind DB file. */ 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); } }