package geoip; import helpers.GH; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.URL; import java.util.Collections; import java.util.zip.GZIPInputStream; import logger.LoggerFactory; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; import com.maxmind.geoip.Country; import com.maxmind.geoip.Location; import com.maxmind.geoip.LookupService; public final class GEOIP { private final boolean country = GEOPref.getBoolean(GEOPref.COUNTRY_ONLY); private final String gzPath = country ? "db/GeoIP.dat.gz" : "db/GeoLiteCity.dat.gz" ; private final String filePath = country ? "db/GeoIP.dat":"db/GeoLiteCity.dat"; private static final Logger logger = LoggerFactory.make(Level.DEBUG); private final LookupService ls ; private static class GEOIPHolder { private static final GEOIP singleton = new GEOIP(); } public static GEOIP get() { return GEOIPHolder.singleton; } private GEOIP() { LookupService ls = null; try { if (!getDBFile().isFile() || GEOPref.isVersionChanged()) { copyToWorkspace(); } ls = new LookupService(getDBFile(), LookupService.GEOIP_MEMORY_CACHE ); } catch(IOException ioe) { logger.warn(ioe, ioe); } this.ls = ls; } /** * * @return true if only country information is available * meaning: * true: getLocation() /may not be called * false .. all may be called.. */ public boolean isCountryOnly() { return country; } /** * @param ip - an IP that should be resolved * @return the location to the IP */ public Location getLocation(String ip) { try { return ls.getLocation(ip); } catch(RuntimeException e) { logger.debug(e,e); } return null; } /** * @param ip - an IP that should be resolved * @return the location to the IP */ public Location getLocation(InetAddress ip) { try { return ls.getLocation(ip); } catch(RuntimeException e) { logger.debug(e+" ip: "+ip,e); } return null; } public Country getCountry(InetAddress ip) { if (country) { try { return ls.getCountry(ip); } catch(RuntimeException e) { logger.debug(e,e); } } else { Location loc = getLocation(ip); if (loc != null) { return new Country(loc.countryCode,loc.countryName); } } return null; } public String getCountryCode(InetAddress ip) { if (country) { Country c = getCountry(ip); return c == null ? null : c.getCode(); } else { Location loc = getLocation(ip); return loc == null? null: loc.countryCode; } } private File getDBFile() { return new File(new File(Platform.getInstanceLocation().getURL().getFile()),filePath); } private void copyToWorkspace() { logger.info(Lang.GEOIPDBUnpacking); Bundle bundle = Platform.getBundle(GEOPref.PLUGIN_ID); Path path = new Path(gzPath); URL url = FileLocator.find(bundle, path, Collections.EMPTY_MAP); FileOutputStream fos = null; GZIPInputStream gis = null; try { InputStream is = url.openStream(); gis = new GZIPInputStream(is); fos = new FileOutputStream(getDBFile()); GH.copy(gis, fos); GEOPref.setVersion(); } catch(IOException ioe) { logger.warn(ioe, ioe); } finally { GH.close(fos,gis); } } }