com.github.tornaia.geoip.GeoIPResidentImpl Maven / Gradle / Ivy
package com.github.tornaia.geoip;
import com.github.tornaia.geoip.internal.IpAddressMatcher;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import static com.github.tornaia.geoip.GeoLiteConstants.IPV_CSV_GEONAME_ID;
import static com.github.tornaia.geoip.GeoLiteConstants.IPV_CSV_REGISTERED_COUNTRY_GEONAME_ID;
import static com.github.tornaia.geoip.GeoLiteConstants.LOCATIONS_CSV_COUNTRY_CODE_ISO;
import static com.github.tornaia.geoip.GeoLiteConstants.LOCATIONS_CSV_GEO_ID;
public class GeoIPResidentImpl implements GeoIP {
private static class MapHolder {
private static final Map CIDR_NOTATIONS_TO_COUNTRY_IDO_CODE_MAP = getCidrNotationsToCountryIdoCodeMap();
private static Map getCidrNotationsToCountryIdoCodeMap() {
Map cidrNotationsToCountryIsoCodeMap = new HashMap<>();
Map countryIdToCountryIsoCodeMap = getCountryIdToCountryIsoCodeMap();
loadIpv4Csv(cidrNotationsToCountryIsoCodeMap, countryIdToCountryIsoCodeMap);
loadIpv6Csv(cidrNotationsToCountryIsoCodeMap, countryIdToCountryIsoCodeMap);
return cidrNotationsToCountryIsoCodeMap;
}
private static void loadIpv4Csv(Map cidrNotationsToCountryIsoCodeMap, Map countryIdToCountryIsoCodeMap) {
loadIpvCsv(cidrNotationsToCountryIsoCodeMap, countryIdToCountryIsoCodeMap, "GeoLite2-Country-Blocks-IPv4.csv");
}
private static void loadIpv6Csv(Map cidrNotationsToCountryIsoCodeMap, Map countryIdToCountryIsoCodeMap) {
loadIpvCsv(cidrNotationsToCountryIsoCodeMap, countryIdToCountryIsoCodeMap, "GeoLite2-Country-Blocks-IPv6.csv");
}
private static void loadIpvCsv(Map cidrNotationsToCountryIsoCodeMap, Map countryIdToCountryIsoCodeMap, String filename) {
try (InputStream inputStream = MapHolder.class.getClassLoader().getResourceAsStream(filename)) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
Map ipMap = reader
.lines()
.skip(1)
.map(e -> e.split(","))
.filter(e -> !e[IPV_CSV_REGISTERED_COUNTRY_GEONAME_ID].isEmpty() || !e[IPV_CSV_GEONAME_ID].isEmpty())
.collect(Collectors.toMap(e -> new IpAddressMatcher(e[LOCATIONS_CSV_GEO_ID]), e -> mapCountryCodeToCountryIsoCode(countryIdToCountryIsoCodeMap, e)));
cidrNotationsToCountryIsoCodeMap.putAll(ipMap);
} catch (IOException e) {
throw new GeoIPException("Failed to read csv: " + filename, e);
}
}
private static Map getCountryIdToCountryIsoCodeMap() {
try (InputStream inputStream = MapHolder.class.getClassLoader().getResourceAsStream("GeoLite2-Country-Locations-en.csv")) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
return reader
.lines()
.skip(1)
.map(e -> e.split(","))
.collect(Collectors.toMap(e -> e[LOCATIONS_CSV_GEO_ID], e -> e[LOCATIONS_CSV_COUNTRY_CODE_ISO]));
} catch (IOException e) {
throw new GeoIPException("Failed to read GeoLite2-Country-Locations-en.csv", e);
}
}
private static String mapCountryCodeToCountryIsoCode(Map countryIdToCountryIsoCodeMap, String[] splittedLine) {
String registeredCountryGeonameId = splittedLine[IPV_CSV_REGISTERED_COUNTRY_GEONAME_ID];
String geonameId = splittedLine[IPV_CSV_GEONAME_ID];
String countryId = registeredCountryGeonameId.isEmpty() ? geonameId : registeredCountryGeonameId;
return getCountryIsoCodeFromCountryId(countryIdToCountryIsoCodeMap, countryId);
}
private static String getCountryIsoCodeFromCountryId(Map countryIdToCountryIsoCodeMap, String countryId) {
String countryIsoCode = countryIdToCountryIsoCodeMap.get(countryId);
boolean countryIsoCodeWasNotFoundForCountryId = countryIsoCode == null;
if (countryIsoCodeWasNotFoundForCountryId) {
throw new GeoIPException("Country iso code was not found for countryId, countryId: " + countryId);
}
return countryIsoCode;
}
private static Map getCidrNotationsToCountryIsoCodeMap() {
return MapHolder.CIDR_NOTATIONS_TO_COUNTRY_IDO_CODE_MAP;
}
}
@Override
public Optional getTwoLetterCountryCode(InetAddress inetAddress) {
return getTwoLetterCountryCode(inetAddress.getHostAddress());
}
@Override
public Optional getTwoLetterCountryCode(String ipAddress) {
return MapHolder.getCidrNotationsToCountryIsoCodeMap()
.entrySet()
.parallelStream()
.filter(e -> e.getKey().matches(ipAddress))
.map(Map.Entry::getValue)
.filter(e -> !e.isEmpty())
.findFirst();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy