// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: ConnectionChecker.java,v 1.21 2006/01/08 05:04:21 kyank Exp $
//
package com.salas.bb.utils;
import com.salas.bb.service.ServerService;
import com.salas.bb.service.ServerServiceException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Checks for connection to Internet with defined periods of time.
*/
public final class ConnectionChecker
{
private static final Logger LOG = Logger.getLogger(ConnectionChecker.class.getName());
// Constants
/**
* Default checking interval (60 seconds).
*/
public static final int DEFAULT_CHECK_INTERVAL = 60;
private static final String OS_NAME = System.getProperty("os.name");
private static final String JAVA_VERSION = System.getProperty("java.version");
// Members
private final ConnectionState connectionState;
private final String version;
private final long installationId;
private final int runs;
private final String accountEmail;
private final String accountPassword;
private int checkInterval;
private boolean started;
// infoSent is used to determine whether info for statistics update sent or not.
// It's too expensive to force server kick database number_of_users times per minute to
// update stats. So, we can do it only once per session while we have once-per-session
// info to pass.
private boolean infoSent;
private Timer timer;
private TimerTask task;
/**
* Creates connection checker.
*
* @param aVersion version of the application.
* @param aInstallationId current installation ID.
* @param aRuns number of application appRuns.
* @param anAccountEmail user's account email.
* @param anAccountpassword user's account password.
* @param aConnectionState state of connection object to update and consult.
*/
public ConnectionChecker(String aVersion, long aInstallationId, int aRuns,
String anAccountEmail, String anAccountpassword, ConnectionState aConnectionState)
{
connectionState = aConnectionState;
version = aVersion;
installationId = aInstallationId;
runs = aRuns;
accountEmail = anAccountEmail;
accountPassword = anAccountpassword;
if (LOG.isLoggable(Level.CONFIG))
{
LOG.config("Version=" + aVersion + " id=" + aInstallationId + " appRuns=" + aRuns);
LOG.config("OS=" + OS_NAME + " Java=" + JAVA_VERSION);
if (LOG.isLoggable(Level.FINE)) LOG.fine("Account Email=" + accountEmail);
}
timer = new Timer(true);
task = new IntervalCheckTask();
checkInterval = DEFAULT_CHECK_INTERVAL;
started = false;
infoSent = false;
}
/**
* Starts checking of connection with currently set interval.
* Checking is not started if interval is less than 1 second.
*/
public synchronized void start()
{
if (started) return;
// Register new checker task
timer.scheduleAtFixedRate(task, 1, checkInterval * Constants.MILLIS_IN_SECOND);
started = true;
}
// Timer task
/**
* Runs once per defined interval of time and tries to get
* measure file from defined URL.
*/
private class IntervalCheckTask extends TimerTask
{
/**
* The action to be performed by this timer task.
*/
public void run()
{
if (connectionState.isOnline())
{
boolean serviceAccessible = isServiceAccessible();
connectionState.setServiceAccessible(serviceAccessible);
synchronized (this)
{
if (serviceAccessible && !infoSent)
{
sendStatisticalInformation();
}
}
}
}
/**
* Pings the server with an empty request to see if it's accessible.
*
* @return <code>TRUE</code> if the service connection attempt was successful.
*/
private boolean isServiceAccessible()
{
if (LOG.isLoggable(Level.FINER)) LOG.finer("Ping");
boolean connected = ServerService.ping();
if (connected && LOG.isLoggable(Level.FINER)) LOG.finer("Pong");
return connected;
}
/**
* Sends package of statistical information to server.
*/
private void sendStatisticalInformation()
{
LOG.fine("Sending statistical information");
try
{
ServerService ss = ServerService.getInstance();
ss.ping(installationId, version, runs, OS_NAME, JAVA_VERSION, accountEmail,
accountPassword);
infoSent = true;
LOG.finer("Statistical information successfully sent.");
} catch (ServerServiceException e)
{
// That's ok. Let's try later.
}
}
}
}