summaryrefslogtreecommitdiff
path: root/src/javax/jmdns/impl/DNSTaskStarter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/javax/jmdns/impl/DNSTaskStarter.java')
-rw-r--r--src/javax/jmdns/impl/DNSTaskStarter.java464
1 files changed, 464 insertions, 0 deletions
diff --git a/src/javax/jmdns/impl/DNSTaskStarter.java b/src/javax/jmdns/impl/DNSTaskStarter.java
new file mode 100644
index 0000000..ab17201
--- /dev/null
+++ b/src/javax/jmdns/impl/DNSTaskStarter.java
@@ -0,0 +1,464 @@
+/**
+ *
+ */
+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.
+ * <p>
+ * <b>Note: </b> This is not considered as part of the general public API of JmDNS.
+ * </p>
+ *
+ * @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 ConcurrentMap<JmDNSImpl, DNSTaskStarter> _instances;
+
+ /**
+ * This interface defines a delegate to the DNSTaskStarter class to enable subclassing.
+ */
+ public static interface ClassDelegate {
+
+ /**
+ * Allows the delegate the opportunity to construct and return a different DNSTaskStarter.
+ *
+ * @param jmDNSImpl
+ * jmDNS instance
+ * @return Should return a new DNSTaskStarter Object.
+ * @see #classDelegate()
+ * @see #setClassDelegate(ClassDelegate anObject)
+ */
+ public DNSTaskStarter newDNSTaskStarter(JmDNSImpl jmDNSImpl);
+ }
+
+ private static final AtomicReference<Factory.ClassDelegate> _databaseClassDelegate = new AtomicReference<Factory.ClassDelegate>();
+
+ private Factory() {
+ super();
+ _instances = new ConcurrentHashMap<JmDNSImpl, DNSTaskStarter>(20);
+ }
+
+ /**
+ * Assigns <code>delegate</code> 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);
+
+}