00001 // Licensed under Apache License version 2.0 00002 package javax.jmdns.impl.tasks.state; 00003 00004 import java.io.IOException; 00005 import java.util.ArrayList; 00006 import java.util.List; 00007 import java.util.logging.Level; 00008 import java.util.logging.Logger; 00009 00010 import javax.jmdns.ServiceInfo; 00011 import javax.jmdns.impl.DNSOutgoing; 00012 import javax.jmdns.impl.DNSStatefulObject; 00013 import javax.jmdns.impl.JmDNSImpl; 00014 import javax.jmdns.impl.ServiceInfoImpl; 00015 import javax.jmdns.impl.constants.DNSConstants; 00016 import javax.jmdns.impl.constants.DNSState; 00017 import javax.jmdns.impl.tasks.DNSTask; 00018 00024 public abstract class DNSStateTask extends DNSTask { 00025 static Logger logger1 = Logger.getLogger(DNSStateTask.class.getName()); 00026 00030 private final int _ttl; 00031 00032 private static int _defaultTTL = DNSConstants.DNS_TTL; 00033 00037 private DNSState _taskState = null; 00038 00039 public abstract String getTaskDescription(); 00040 00041 public static int defaultTTL() { 00042 return _defaultTTL; 00043 } 00044 00050 public static void setDefaultTTL(int value) { 00051 _defaultTTL = value; 00052 } 00053 00058 public DNSStateTask(JmDNSImpl jmDNSImpl, int ttl) { 00059 super(jmDNSImpl); 00060 _ttl = ttl; 00061 } 00062 00066 public int getTTL() { 00067 return _ttl; 00068 } 00069 00076 protected void associate(DNSState state) { 00077 synchronized (this.getDns()) { 00078 this.getDns().associateWithTask(this, state); 00079 } 00080 for (ServiceInfo serviceInfo : this.getDns().getServices().values()) { 00081 ((ServiceInfoImpl) serviceInfo).associateWithTask(this, state); 00082 } 00083 } 00084 00088 protected void removeAssociation() { 00089 // Remove association from host to this 00090 synchronized (this.getDns()) { 00091 this.getDns().removeAssociationWithTask(this); 00092 } 00093 00094 // Remove associations from services to this 00095 for (ServiceInfo serviceInfo : this.getDns().getServices().values()) { 00096 ((ServiceInfoImpl) serviceInfo).removeAssociationWithTask(this); 00097 } 00098 } 00099 00100 @Override 00101 public void run() { 00102 DNSOutgoing out = this.createOugoing(); 00103 try { 00104 if (!this.checkRunCondition()) { 00105 this.cancel(); 00106 return; 00107 } 00108 List<DNSStatefulObject> stateObjects = new ArrayList<DNSStatefulObject>(); 00109 // send probes for JmDNS itself 00110 synchronized (this.getDns()) { 00111 if (this.getDns().isAssociatedWithTask(this, this.getTaskState())) { 00112 logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + this.getDns().getName()); 00113 stateObjects.add(this.getDns()); 00114 out = this.buildOutgoingForDNS(out); 00115 } 00116 } 00117 // send probes for services 00118 for (ServiceInfo serviceInfo : this.getDns().getServices().values()) { 00119 ServiceInfoImpl info = (ServiceInfoImpl) serviceInfo; 00120 00121 synchronized (info) { 00122 if (info.isAssociatedWithTask(this, this.getTaskState())) { 00123 logger1.fine(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " " + info.getQualifiedName()); 00124 stateObjects.add(info); 00125 out = this.buildOutgoingForInfo(info, out); 00126 } 00127 } 00128 } 00129 if (!out.isEmpty()) { 00130 logger1.finer(this.getName() + ".run() JmDNS " + this.getTaskDescription() + " #" + this.getTaskState()); 00131 this.getDns().send(out); 00132 00133 // Advance the state of objects. 00134 this.advanceObjectsState(stateObjects); 00135 } else { 00136 // Advance the state of objects. 00137 this.advanceObjectsState(stateObjects); 00138 00139 // If we have nothing to send, another timer taskState ahead of us has done the job for us. We can cancel. 00140 cancel(); 00141 return; 00142 } 00143 } catch (Throwable e) { 00144 logger1.log(Level.WARNING, this.getName() + ".run() exception ", e); 00145 this.recoverTask(e); 00146 } 00147 00148 this.advanceTask(); 00149 } 00150 00151 protected abstract boolean checkRunCondition(); 00152 00153 protected abstract DNSOutgoing buildOutgoingForDNS(DNSOutgoing out) throws IOException; 00154 00155 protected abstract DNSOutgoing buildOutgoingForInfo(ServiceInfoImpl info, DNSOutgoing out) throws IOException; 00156 00157 protected abstract DNSOutgoing createOugoing(); 00158 00159 protected void advanceObjectsState(List<DNSStatefulObject> list) { 00160 if (list != null) { 00161 for (DNSStatefulObject object : list) { 00162 synchronized (object) { 00163 object.advanceState(this); 00164 } 00165 } 00166 } 00167 } 00168 00169 protected abstract void recoverTask(Throwable e); 00170 00171 protected abstract void advanceTask(); 00172 00176 protected DNSState getTaskState() { 00177 return this._taskState; 00178 } 00179 00184 protected void setTaskState(DNSState taskState) { 00185 this._taskState = taskState; 00186 } 00187 00188 }