Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: Freenet/message/Request.java


1   package Freenet.message;
2   import Freenet.*;
3   import Freenet.node.*;
4   import Freenet.support.*;
5   import java.util.*;
6   
7   public abstract class Request extends Message {
8   
9     public Key searchKey;
10  
11    public Request(long idnum, long htl, long depth, Key key)
12    {
13      super(idnum, htl, depth);
14      searchKey=key;
15    }
16  
17    public Request(RawMessage raw) throws InvalidMessageException
18    {
19      super(raw);
20      searchKey=new StringKey(popField("SearchKey"));
21      if(searchKey.toString()==null) throw new InvalidMessageException
22          ("Can't find SearchKey field");
23    }
24  
25    public RawMessage toRawMessage()
26    {
27      RawMessage raw=super.toRawMessage();
28      raw.setField("SearchKey", searchKey.toString());
29      return raw;
30    }
31  
32    /**
33     * Called by a node after it receives this message
34     * @param n The node that called this message.  This should be used
35     *          to make any nescessary modifications to the DataStore etc.
36     * @param sb Null unless this node has been seen before.  If non-null it
37     *           is the Object returned by the received method of the
38     *           last message seen with this ID.
39     * @return The object to be passed to any messages received in the near
40     *         future with the same ID as this one.  Null if no object should
41     *         be passed.
42     **/
43    public MessageMemory pReceived(Node n, MessageMemory sb)
44    {
45      if(sb!=null) // Uh-oh! Must be a loop.
46      {
47          Logger.log("message/Request","loop - backtracking",Logger.MINOR);
48    RequestFailed rf=new RequestFailed(id, hopsToLive);
49    try {
50        sendReply(n, rf);
51         // we expect no further connections from this node, so we close the connection after sending
52    } catch(SendFailedException sfe) {
53        Logger.log("message/Request.java","Return to " + sfe.peer + " failed on loop",Logger.NORMAL);
54    }
55    return sb;
56      }
57      
58      Data data;
59      Address ref;
60  
61      if ((data=n.ds.searchData(searchKey))!=null) { // I have the data
62    try {
63        dataFound(data, n);
64    } catch (RequestAbortException rae) {
65        return rae.mm;
66    }
67      } else if ((ref=n.ds.searchRef(searchKey))!=null) { // Reference found
68    try {
69        refFound(ref, n);
70    } catch (RequestAbortException rae) {
71        return rae.mm;
72    }
73      }
74  
75    
76      // Going on forward the query
77      Logger.log("message/Request.java","Forwarding query for " + searchKey,Logger.MINOR);
78      Address addr; boolean failed; 
79  
80      KeyedMM kmm=new KeyedMM(source, depth, receivedWith, searchKey, null, this.getClass());
81  
82      do { // until the send doesn't fail
83          do { // until the reference isn't back or used
84              kmm.lastAttempt=n.ds.findClosestKey(searchKey,kmm.lastAttempt);
85              addr=n.ds.searchRef(kmm.lastAttempt);
86          } while (addr != null && (addr.equals(kmm.origRec)
87                                    || kmm.usedAddresses.contains(addr)) );
88  
89    if(kmm.lastAttempt==null) // Out of references
90        {
91      Logger.log("message/Request.java","No more nodes to send " + Long.toHexString(id) + " to, returning to " + kmm.origRec,Logger.MINOR);
92      RequestFailed rf=new RequestFailed(id, hopsToLive);
93      try {
94          rf.sendBack(n,kmm);
95      } catch(SendFailedException sfe) {
96          Logger.log("message/Request.java","Return to " + sfe.peer + " failed on no more references",Logger.NORMAL);
97      }
98      return kmm;
99        }
100 
101         // mark that we've already tried to send to this address
102         kmm.usedAddresses.addElement(addr);
103 
104   failed = false;
105   try {
106       Logger.log("message/Request.java","Forwarding query to " + addr,Logger.MINOR);
107       ConnectionHandler ch = n.makeConnection(addr);
108       sending(n, ch);
109       ch.sendMessage(this, null, null);
110   } catch(ConnectFailedException cfe) {
111       failed = true;
112   } catch(SendFailedException sfe) {
113       failed = true;
114   }
115     } while (failed);
116 
117     kmm.lastAddr = addr;
118 
119     // add a timer callback to time out on no reply
120     Node.timer.add(id, hopsToLive * Node.timePerHop, new RequestCB(n, kmm, id, hopsToLive));
121 
122     return kmm;
123   }
124 
125     /*
126      * method should is called when RequestFailed times out. It should be 
127      * overwritten to mirror the different timeout behaviour of
128      * different requests
129      */
130 
131     public static KeyedMM failedTimedOut(Node n, long id, KeyedMM kmm) {
132   Logger.log("message/Request.java","right right right",Logger.DEBUGGING);
133   // Cancel existing timeout
134   n.timer.cancel(id);
135 
136   TimedOut to=new TimedOut(id, kmm.depth);
137     
138   try {
139       to.sendBack(n, kmm);
140   } catch(SendFailedException sfe) {
141       Logger.log("Request.java","Sending of timeout to Failed message failed",Logger.NORMAL);
142   }
143   return null;
144     }
145 
146     //Private & Protected methods
147 
148     public static class RequestAbortException extends Exception {
149   MessageMemory mm;
150   public RequestAbortException(MessageMemory mm) {
151       this.mm = mm;
152   }
153     }
154 
155 
156     /*
157      * This method is called if a ref is found to the searchkey of the
158      * the request. To abort the current request, throw a RequestAbortException
159      * containing the MM to be returned.
160      */
161     protected abstract void refFound(Address ref, Node n) throws RequestAbortException;
162     /*
163      * This method is called if data is found to the searchkey of the
164      * the request. To abort the current request, throw a RequestAbortException
165      * containing the MM to be returned.
166      */
167     protected abstract void dataFound(Data data, Node n) throws RequestAbortException;
168 
169     protected MessageMemory timeOut(Node n, MessageMemory mm) {
170 
171   Data data;
172   Address ref;
173 
174   if ((data=n.ds.searchData(searchKey))!=null) { // I have the data
175       try {
176     dataFound(data, n);
177       } catch (RequestAbortException rae) {
178     return rae.mm;
179       }
180   } else if ((ref=n.ds.searchRef(searchKey))!=null) { // Reference found
181       try {
182     refFound(ref, n);
183       } catch (RequestAbortException rae) {
184     return rae.mm;
185       }
186   }
187   if (mm != null && mm instanceof KeyedMM) 
188       ((KeyedMM) mm).pending = false; 
189 
190   return super.timeOut(n, mm);
191     }
192 }
193