1 // Licensed under Apache License version 2.0
2 package javax.jmdns.impl.tasks.resolver;
3 
4 import java.io.IOException;
5 import java.util.Timer;
6 import java.util.logging.Level;
7 import java.util.logging.Logger;
8 
9 import javax.jmdns.impl.DNSOutgoing;
10 import javax.jmdns.impl.JmDNSImpl;
11 import javax.jmdns.impl.constants.DNSConstants;
12 import javax.jmdns.impl.tasks.DNSTask;
13 
14 /**
15  * This is the root class for all resolver tasks.
16  *
17  * @author Pierre Frisch
18  */
19 public abstract class DNSResolverTask extends DNSTask {
20     private static Logger logger = Logger.getLogger(DNSResolverTask.class.getName());
21 
22     /**
23      * Counts the number of queries being sent.
24      */
25     protected int         _count = 0;
26 
27     /**
28      * @param jmDNSImpl
29      */
DNSResolverTask(JmDNSImpl jmDNSImpl)30     public DNSResolverTask(JmDNSImpl jmDNSImpl) {
31         super(jmDNSImpl);
32     }
33 
34     /*
35      * (non-Javadoc)
36      * @see java.lang.Object#toString()
37      */
38     @Override
toString()39     public String toString() {
40         return super.toString() + " count: " + _count;
41     }
42 
43     /*
44      * (non-Javadoc)
45      * @see javax.jmdns.impl.tasks.DNSTask#start(java.util.Timer)
46      */
47     @Override
start(Timer timer)48     public void start(Timer timer) {
49         if (!this.getDns().isCanceling() && !this.getDns().isCanceled()) {
50             timer.schedule(this, DNSConstants.QUERY_WAIT_INTERVAL, DNSConstants.QUERY_WAIT_INTERVAL);
51         }
52     }
53 
54     /*
55      * (non-Javadoc)
56      * @see java.util.TimerTask#run()
57      */
58     @Override
run()59     public void run() {
60         try {
61             if (this.getDns().isCanceling() || this.getDns().isCanceled()) {
62                 this.cancel();
63             } else {
64                 if (_count++ < 3) {
65                     if (logger.isLoggable(Level.FINER)) {
66                         logger.finer(this.getName() + ".run() JmDNS " + this.description());
67                     }
68                     DNSOutgoing out = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY);
69                     out = this.addQuestions(out);
70                     if (this.getDns().isAnnounced()) {
71                         out = this.addAnswers(out);
72                     }
73                     if (!out.isEmpty()) {
74                         this.getDns().send(out);
75                     }
76                 } else {
77                     // After three queries, we can quit.
78                     this.cancel();
79                 }
80             }
81         } catch (Throwable e) {
82             logger.log(Level.WARNING, this.getName() + ".run() exception ", e);
83             this.getDns().recover();
84         }
85     }
86 
87     /**
88      * Overridden by subclasses to add questions to the message.<br/>
89      * <b>Note:</b> Because of message size limitation the returned message may be different than the message parameter.
90      *
91      * @param out
92      *            outgoing message
93      * @return the outgoing message.
94      * @exception IOException
95      */
addQuestions(DNSOutgoing out)96     protected abstract DNSOutgoing addQuestions(DNSOutgoing out) throws IOException;
97 
98     /**
99      * Overridden by subclasses to add questions to the message.<br/>
100      * <b>Note:</b> Because of message size limitation the returned message may be different than the message parameter.
101      *
102      * @param out
103      *            outgoing message
104      * @return the outgoing message.
105      * @exception IOException
106      */
addAnswers(DNSOutgoing out)107     protected abstract DNSOutgoing addAnswers(DNSOutgoing out) throws IOException;
108 
109     /**
110      * Returns a description of the resolver for debugging
111      *
112      * @return resolver description
113      */
description()114     protected abstract String description();
115 
116 }
117