summaryrefslogtreecommitdiff
path: root/src/javax/jmdns/impl/tasks/state/DNSStateTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/javax/jmdns/impl/tasks/state/DNSStateTask.java')
-rw-r--r--src/javax/jmdns/impl/tasks/state/DNSStateTask.java188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/javax/jmdns/impl/tasks/state/DNSStateTask.java b/src/javax/jmdns/impl/tasks/state/DNSStateTask.java
new file mode 100644
index 0000000..a0896d9
--- /dev/null
+++ b/src/javax/jmdns/impl/tasks/state/DNSStateTask.java
@@ -0,0 +1,188 @@
+// Licensed under Apache License version 2.0
+package javax.jmdns.impl.tasks.state;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.impl.DNSOutgoing;
+import javax.jmdns.impl.DNSStatefulObject;
+import javax.jmdns.impl.JmDNSImpl;
+import javax.jmdns.impl.ServiceInfoImpl;
+import javax.jmdns.impl.constants.DNSConstants;
+import javax.jmdns.impl.constants.DNSState;
+import javax.jmdns.impl.tasks.DNSTask;
+
+/**
+ * This is the root class for all state tasks. These tasks work with objects that implements the {@link javax.jmdns.impl.DNSStatefulObject} interface and therefore participate in the state machine.
+ *
+ * @author Pierre Frisch
+ */
+public abstract class DNSStateTask extends DNSTask {
+ static Logger logger1 = Logger.getLogger(DNSStateTask.class.getName());
+
+ /**
+ * By setting a 0 ttl we effectively expire the record.
+ */
+ private final int _ttl;
+
+ private static int _defaultTTL = DNSConstants.DNS_TTL;
+
+ /**
+ * The state of the task.
+ */
+ private DNSState _taskState = null;
+
+ public abstract String getTaskDescription();
+
+ public static int defaultTTL() {
+ return _defaultTTL;
+ }
+
+ /**
+ * For testing only do not use in production.
+ *
+ * @param value
+ */
+ public static void setDefaultTTL(int value) {
+ _defaultTTL = value;
+ }
+
+ /**
+ * @param jmDNSImpl
+ * @param ttl
+ */
+ public DNSStateTask(JmDNSImpl jmDNSImpl, int ttl) {
+ super(jmDNSImpl);
+ _ttl = ttl;
+ }
+
+ /**
+ * @return the ttl
+ */
+ public int getTTL() {
+ return _ttl;
+ }
+
+ /**
+ * Associate the DNS host and the service infos with this task if not already associated and in the same state.
+ *
+ * @param state
+ * target state
+ */
+ protected void associate(DNSState state) {
+ synchronized (this.getDns()) {
+ this.getDns().associateWithTask(this, state);
+ }
+ for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
+ ((ServiceInfoImpl) serviceInfo).associateWithTask(this, state);
+ }
+ }
+
+ /**
+ * Remove the DNS host and service info association with this task.
+ */
+ protected void removeAssociation() {
+ // Remove association from host to this
+ synchronized (this.getDns()) {
+ this.getDns().removeAssociationWithTask(this);
+ }
+
+ // Remove associations from services to this
+ for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
+ ((ServiceInfoImpl) serviceInfo).removeAssociationWithTask(this);
+ }
+ }
+
+ @Override
+ public void run() {
+ DNSOutgoing out = this.createOugoing();
+ try {
+ if (!this.checkRunCondition()) {
+ this.cancel();
+ return;
+ }
+ List<DNSStatefulObject> stateObjects = new ArrayList<DNSStatefulObject>();
+ // send probes for JmDNS itself
+ synchronized (this.getDns()) {
+ if (this.getDns().isAssociatedWithTask(this, this.getTaskState())) {
+ logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + this.getDns().getName());
+ stateObjects.add(this.getDns());
+ out = this.buildOutgoingForDNS(out);
+ }
+ }
+ // send probes for services
+ for (ServiceInfo serviceInfo : this.getDns().getServices().values()) {
+ ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo;
+
+ synchronized (info) {
+ if (info.isAssociatedWithTask(this, this.getTaskState())) {
+ logger1.fine(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + info.getQualifiedName());
+ stateObjects.add(info);
+ out = this.buildOutgoingForInfo(info, out);
+ }
+ }
+ }
+ if (!out.isEmpty()) {
+ logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " #" + this.getTaskState());
+ this.getDns().send(out);
+
+ // Advance the state of objects.
+ this.advanceObjectsState(stateObjects);
+ } else {
+ // Advance the state of objects.
+ this.advanceObjectsState(stateObjects);
+
+ // If we have nothing to send, another timer taskState ahead of us has done the job for us. We can cancel.
+ cancel();
+ return;
+ }
+ } catch (Throwable e) {
+ logger1.log(Level.WARNING, this.getName() + ".run() exception ", e);
+ this.recoverTask(e);
+ }
+
+ this.advanceTask();
+ }
+
+ protected abstract boolean checkRunCondition();
+
+ protected abstract DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException;
+
+ protected abstract DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException;
+
+ protected abstract DNSOutgoing createOugoing();
+
+ protected void advanceObjectsState(List<DNSStatefulObject> list) {
+ if (list != null) {
+ for (DNSStatefulObject object : list) {
+ synchronized (object) {
+ object.advanceState(this);
+ }
+ }
+ }
+ }
+
+ protected abstract void recoverTask(Throwable e);
+
+ protected abstract void advanceTask();
+
+ /**
+ * @return the taskState
+ */
+ protected DNSState getTaskState() {
+ return this._taskState;
+ }
+
+ /**
+ * @param taskState
+ * the taskState to set
+ */
+ protected void setTaskState(DNSState taskState) {
+ this._taskState = taskState;
+ }
+
+}