/** * */ package javax.jmdns.impl; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReference; import javax.jmdns.impl.tasks.RecordReaper; import javax.jmdns.impl.tasks.Responder; import javax.jmdns.impl.tasks.resolver.ServiceInfoResolver; import javax.jmdns.impl.tasks.resolver.ServiceResolver; import javax.jmdns.impl.tasks.resolver.TypeResolver; import javax.jmdns.impl.tasks.state.Announcer; import javax.jmdns.impl.tasks.state.Canceler; import javax.jmdns.impl.tasks.state.Prober; import javax.jmdns.impl.tasks.state.Renewer; /** * This class is used by JmDNS to start the various task required to run the DNS discovery. This interface is only there in order to support MANET modifications. *
* Note: This is not considered as part of the general public API of JmDNS. *
* * @author Pierre Frisch */ public interface DNSTaskStarter { /** * DNSTaskStarter.Factory enable the creation of new instance of DNSTaskStarter. */ public static final class Factory { private static volatile Factory _instance; private final ConcurrentMapdelegate
as DNSTaskStarter's class delegate. The class delegate is optional.
*
* @param delegate
* The object to set as DNSTaskStarter's class delegate.
* @see #classDelegate()
* @see DNSTaskStarter.Factory.ClassDelegate
*/
public static void setClassDelegate(Factory.ClassDelegate delegate) {
_databaseClassDelegate.set(delegate);
}
/**
* Returns DNSTaskStarter's class delegate.
*
* @return DNSTaskStarter's class delegate.
* @see #setClassDelegate(ClassDelegate anObject)
* @see DNSTaskStarter.Factory.ClassDelegate
*/
public static Factory.ClassDelegate classDelegate() {
return _databaseClassDelegate.get();
}
/**
* Returns a new instance of DNSTaskStarter using the class delegate if it exists.
*
* @param jmDNSImpl
* jmDNS instance
* @return new instance of DNSTaskStarter
*/
protected static DNSTaskStarter newDNSTaskStarter(JmDNSImpl jmDNSImpl) {
DNSTaskStarter instance = null;
Factory.ClassDelegate delegate = _databaseClassDelegate.get();
if (delegate != null) {
instance = delegate.newDNSTaskStarter(jmDNSImpl);
}
return (instance != null ? instance : new DNSTaskStarterImpl(jmDNSImpl));
}
/**
* Return the instance of the DNSTaskStarter Factory.
*
* @return DNSTaskStarter Factory
*/
public static Factory getInstance() {
if (_instance == null) {
synchronized (DNSTaskStarter.Factory.class) {
if (_instance == null) {
_instance = new Factory();
}
}
}
return _instance;
}
/**
* Return the instance of the DNSTaskStarter for the JmDNS.
*
* @param jmDNSImpl
* jmDNS instance
* @return the DNSTaskStarter
*/
public DNSTaskStarter getStarter(JmDNSImpl jmDNSImpl) {
DNSTaskStarter starter = _instances.get(jmDNSImpl);
if (starter == null) {
_instances.putIfAbsent(jmDNSImpl, newDNSTaskStarter(jmDNSImpl));
starter = _instances.get(jmDNSImpl);
}
return starter;
}
}
public static final class DNSTaskStarterImpl implements DNSTaskStarter {
private final JmDNSImpl _jmDNSImpl;
/**
* The timer is used to dispatch all outgoing messages of JmDNS. It is also used to dispatch maintenance tasks for the DNS cache.
*/
private final Timer _timer;
/**
* The timer is used to dispatch maintenance tasks for the DNS cache.
*/
private final Timer _stateTimer;
public static class StarterTimer extends Timer {
// This is needed because in some case we cancel the timers before all the task have finished running and in some case they will try to reschedule
private volatile boolean _cancelled;
/**
*
*/
public StarterTimer() {
super();
_cancelled = false;
}
/**
* @param isDaemon
*/
public StarterTimer(boolean isDaemon) {
super(isDaemon);
_cancelled = false;
}
/**
* @param name
* @param isDaemon
*/
public StarterTimer(String name, boolean isDaemon) {
super(name, isDaemon);
_cancelled = false;
}
/**
* @param name
*/
public StarterTimer(String name) {
super(name);
_cancelled = false;
}
/*
* (non-Javadoc)
* @see java.util.Timer#cancel()
*/
@Override
public synchronized void cancel() {
if (_cancelled) return;
_cancelled = true;
super.cancel();
}
/*
* (non-Javadoc)
* @see java.util.Timer#schedule(java.util.TimerTask, long)
*/
@Override
public synchronized void schedule(TimerTask task, long delay) {
if (_cancelled) return;
super.schedule(task, delay);
}
/*
* (non-Javadoc)
* @see java.util.Timer#schedule(java.util.TimerTask, java.util.Date)
*/
@Override
public synchronized void schedule(TimerTask task, Date time) {
if (_cancelled) return;
super.schedule(task, time);
}
/*
* (non-Javadoc)
* @see java.util.Timer#schedule(java.util.TimerTask, long, long)
*/
@Override
public synchronized void schedule(TimerTask task, long delay, long period) {
if (_cancelled) return;
super.schedule(task, delay, period);
}
/*
* (non-Javadoc)
* @see java.util.Timer#schedule(java.util.TimerTask, java.util.Date, long)
*/
@Override
public synchronized void schedule(TimerTask task, Date firstTime, long period) {
if (_cancelled) return;
super.schedule(task, firstTime, period);
}
/*
* (non-Javadoc)
* @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, long, long)
*/
@Override
public synchronized void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (_cancelled) return;
super.scheduleAtFixedRate(task, delay, period);
}
/*
* (non-Javadoc)
* @see java.util.Timer#scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long)
*/
@Override
public synchronized void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
if (_cancelled) return;
super.scheduleAtFixedRate(task, firstTime, period);
}
}
public DNSTaskStarterImpl(JmDNSImpl jmDNSImpl) {
super();
_jmDNSImpl = jmDNSImpl;
_timer = new StarterTimer("JmDNS(" + _jmDNSImpl.getName() + ").Timer", true);
_stateTimer = new StarterTimer("JmDNS(" + _jmDNSImpl.getName() + ").State.Timer", false);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#purgeTimer()
*/
@Override
public void purgeTimer() {
_timer.purge();
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#purgeStateTimer()
*/
@Override
public void purgeStateTimer() {
_stateTimer.purge();
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#cancelTimer()
*/
@Override
public void cancelTimer() {
_timer.cancel();
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#cancelStateTimer()
*/
@Override
public void cancelStateTimer() {
_stateTimer.cancel();
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startProber()
*/
@Override
public void startProber() {
new Prober(_jmDNSImpl).start(_stateTimer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startAnnouncer()
*/
@Override
public void startAnnouncer() {
new Announcer(_jmDNSImpl).start(_stateTimer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startRenewer()
*/
@Override
public void startRenewer() {
new Renewer(_jmDNSImpl).start(_stateTimer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startCanceler()
*/
@Override
public void startCanceler() {
new Canceler(_jmDNSImpl).start(_stateTimer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startReaper()
*/
@Override
public void startReaper() {
new RecordReaper(_jmDNSImpl).start(_timer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startServiceInfoResolver(javax.jmdns.impl.ServiceInfoImpl)
*/
@Override
public void startServiceInfoResolver(ServiceInfoImpl info) {
new ServiceInfoResolver(_jmDNSImpl, info).start(_timer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startTypeResolver()
*/
@Override
public void startTypeResolver() {
new TypeResolver(_jmDNSImpl).start(_timer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startServiceResolver(java.lang.String)
*/
@Override
public void startServiceResolver(String type) {
new ServiceResolver(_jmDNSImpl, type).start(_timer);
}
/*
* (non-Javadoc)
* @see javax.jmdns.impl.DNSTaskStarter#startResponder(javax.jmdns.impl.DNSIncoming, int)
*/
@Override
public void startResponder(DNSIncoming in, int port) {
new Responder(_jmDNSImpl, in, port).start(_timer);
}
}
/**
* Purge the general task timer
*/
public void purgeTimer();
/**
* Purge the state task timer
*/
public void purgeStateTimer();
/**
* Cancel the generals task timer
*/
public void cancelTimer();
/**
* Cancel the state task timer
*/
public void cancelStateTimer();
/**
* Start a new prober task
*/
public void startProber();
/**
* Start a new announcer task
*/
public void startAnnouncer();
/**
* Start a new renewer task
*/
public void startRenewer();
/**
* Start a new canceler task
*/
public void startCanceler();
/**
* Start a new reaper task. There is only supposed to be one reaper running at a time.
*/
public void startReaper();
/**
* Start a new service info resolver task
*
* @param info
* service info to resolve
*/
public void startServiceInfoResolver(ServiceInfoImpl info);
/**
* Start a new service type resolver task
*/
public void startTypeResolver();
/**
* Start a new service resolver task
*
* @param type
* service type to resolve
*/
public void startServiceResolver(String type);
/**
* Start a new responder task
*
* @param in
* incoming message
* @param port
* incoming port
*/
public void startResponder(DNSIncoming in, int port);
}