package polly.dyndns.core; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import de.skuzzle.jeve.EventProvider; import de.skuzzle.polly.sdk.time.Time; import de.skuzzle.polly.tools.concurrent.ThreadFactoryBuilder; public class PublicIpFinder { private final static String API_URL = "http://www.skuzzle.de/ip.php"; //$NON-NLS-1$ private volatile String lastKnownIp; private volatile long lastUpdate; private final ScheduledExecutorService updater; private final EventProvider eventProvider; private final Logger logger; private final class UpdateRunnable implements Runnable { private final boolean forceUpdate; public UpdateRunnable(boolean forceUpdate) { this.forceUpdate = forceUpdate; } @Override public void run() { logger.info("Obtaining new IP from '" + API_URL + "'"); //$NON-NLS-1$ //$NON-NLS-2$ try { final URL url = new URL(API_URL); final URLConnection connection = url.openConnection(); try (BufferedReader r = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { final String line = r.readLine(); synchronized (PublicIpFinder.this) { if (this.forceUpdate || line != null && !line.equals(lastKnownIp)) { logger.info("Public IP has changed from " + //$NON-NLS-1$ lastKnownIp + " to " + line + ", forced: " + //$NON-NLS-1$ //$NON-NLS-2$ this.forceUpdate); final IPChangedEvent e = new IPChangedEvent( PublicIpFinder.this, line); fireIPChangedEvent(e); lastKnownIp = line; lastUpdate = Time.currentTimeMillis(); } } } } catch (Exception e) { logger.error("Error while retrieving current public API", e); //$NON-NLS-1$ e.printStackTrace(); } } } /** * * @param loggerName Name of the logger * @param updateInterval Interval in which this class checks for IP changes * (in minutes). */ public PublicIpFinder(String loggerName, int updateInterval) { this.logger = Logger.getLogger(loggerName); this.eventProvider = EventProvider.newDefaultEventProvider(); this.updater = Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder("DynDNS_Service").setDaemon(false)); //$NON-NLS-1$ this.updater.scheduleAtFixedRate(new UpdateRunnable(false), updateInterval, updateInterval, TimeUnit.MINUTES); } public String getLastKnownIp() { return this.lastKnownIp; } public long getLastUpdate() { return this.lastUpdate; } public void updateNow() { new UpdateRunnable(true).run(); } public void addIPChangedListener(IPChangedListener listener) { this.eventProvider.addListener(IPChangedListener.class, listener); } public void removeIPChangedListener(IPChangedListener listener) { this.eventProvider.addListener(IPChangedListener.class, listener); } protected void fireIPChangedEvent(IPChangedEvent e) { this.eventProvider.dispatch(IPChangedListener.class, e, IPChangedListener::ipChanged); } }