KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mr > core > net > TransportTable


1 /*
2  * Copyright 2002 by
3  * <a HREF="http://www.coridan.com">Coridan</a>
4  * <a HREF="mailto: support@coridan.com ">support@coridan.com</a>
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is "MantaRay" (TM).
17  *
18  * The Initial Developer of the Original Code is Uri Schneider.
19  * Portions created by the Initial Developer are Copyright (C) 2006
20  * Coridan Inc. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source
23  * code where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LESSER GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above. If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LESSER GENERAL PUBLIC LICENSE.
34  
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Lesser General Public License as published by the Free Software Foundation;
39  * either version 2.1 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
44  * License for more details.
45  */

46 package org.mr.core.net;
47
48 /**
49  * TransportTable.java
50  *
51  * A container class for transports.
52  *
53  * Created: Mon Jan 19 20:02:23 2004
54  *
55  * @author Uri Schneider
56  * @version 1.0
57  */

58
59 import java.io.IOException JavaDoc;
60 import java.net.InetAddress JavaDoc;
61 import java.net.InetSocketAddress JavaDoc;
62 import java.net.SocketAddress JavaDoc;
63 import java.nio.channels.SocketChannel JavaDoc;
64 import java.util.*;
65
66 import org.apache.commons.logging.Log;
67 import org.apache.commons.logging.LogFactory;
68
69 public class TransportTable {
70     private HashMap agentTable;
71     private HashMap addressTable;
72     private HashMap udpAddressTable;
73     private HashMap localTCPTable;
74     private HashMap pendingTable;
75     private HashMap indirectTable;
76     private HashMap agentAccessibleCache;
77     private Log log;
78
79 // private static CDPMaster staticCDP;
80

81     /**
82      * Default Constructor
83      */

84     public TransportTable() {
85         this.agentTable = new HashMap();
86         this.addressTable = new HashMap();
87         this.localTCPTable = new HashMap();
88         this.pendingTable = new HashMap();
89         this.indirectTable = new HashMap();
90         this.agentAccessibleCache = new HashMap();
91         this.log = LogFactory.getLog("TransportTable");
92     } // TransportTable constructor
93

94     public synchronized void addAgent(String JavaDoc agent, Set transports) {
95         Iterator i = transports.iterator();
96         while (i.hasNext()) {
97             Transport t = (Transport) i.next();
98             TransportInfo info = t.getInfo();
99             addressTable.put(info.getSocketAddress(), t);
100         }
101         agentTable.put(agent, transports);
102         agentAccessibleCache.remove(agent);
103     }
104
105     public synchronized void addTransport(String JavaDoc agent, Transport t) {
106         Set transports = (Set) agentTable.get(agent);
107         if (transports != null) {
108             transports.add(t);
109
110             if (t.isIndirect()) {
111                 this.indirectTable.put(agent, t);
112             } else {
113                 TransportInfo info = t.getInfo();
114                 if (!t.isPassive()) {
115                     Transport old = (Transport)
116                         addressTable.put(info.getSocketAddress(), t);
117                     if (old != null) {
118                         // a new agent has advertised itself with the
119
// address of an existing one - shutdown the old one.
120
old.shutdown();
121                     }
122                 }
123             }
124         }
125         agentAccessibleCache.remove(agent);
126     }
127
128     public synchronized Set removeAgent(String JavaDoc agent) {
129         Set transports = (Set) agentTable.remove(agent);
130         if (transports != null) {
131             Iterator i = transports.iterator();
132             while (i.hasNext()) {
133                 TransportInfo info = ((Transport) i.next()).getInfo();
134                 addressTable.remove(info.getSocketAddress());
135             }
136         }
137         agentAccessibleCache.remove(agent);
138
139         return transports;
140     }
141
142     public synchronized Transport removeTransport(String JavaDoc agent,
143                                                   SocketAddress JavaDoc addr,
144                                                   boolean indirect)
145     {
146         Set transports = (Set) agentTable.get(agent);
147         Transport t = null;
148
149         if (indirect) {
150             t = (Transport) indirectTable.remove(agent);
151         } else {
152             t = (Transport) addressTable.remove(addr);
153             if (t == null) {
154                 t = (Transport) udpAddressTable.remove(((InetSocketAddress JavaDoc) addr).getAddress());
155             }
156         }
157         if (t != null) {
158             transports.remove(t);
159         }
160         agentAccessibleCache.remove(agent);
161
162         return t;
163     }
164
165     public synchronized Collection getLocalTransports() {
166         return this.localTCPTable.values();
167     }
168
169     public synchronized void addLocalTransport(LocalTransport t) {
170         SocketAddress JavaDoc addr = t.getSocketAddress();
171         InetSocketAddress JavaDoc iaddr = (InetSocketAddress JavaDoc) addr;
172         localTCPTable.put(addr, t);
173         agentAccessibleCache.clear();
174     }
175
176     public synchronized LocalTransport removeLocalTransport(SocketAddress JavaDoc addr)
177     {
178         agentAccessibleCache.clear();
179         return (LocalTransport) localTCPTable.remove(addr);
180     }
181
182     public synchronized LocalTransport getLocalTransport(SocketAddress JavaDoc addr) {
183         return (LocalTransport) localTCPTable.get(addr);
184     }
185
186     public synchronized TransportImpl
187         addPendingTransport(SocketChannel JavaDoc channel, NetworkListener listener) {
188         SocketAddress JavaDoc localAddr = channel.socket().getLocalSocketAddress();
189         SocketAddress JavaDoc remoteAddr = channel.socket().getRemoteSocketAddress();
190         LocalTCPTransport localTran =
191             (LocalTCPTransport) localTCPTable.get(localAddr);
192         TransportImpl impl = null;
193
194         if (localTran == null) {
195             try {
196                 int port = ((InetSocketAddress JavaDoc) localAddr).getPort();
197                 localAddr = new InetSocketAddress JavaDoc("0.0.0.0", port);
198                 localTran = (LocalTCPTransport) localTCPTable.get(localAddr);
199             } catch (Exception JavaDoc e) {}
200         }
201         if(log.isInfoEnabled()){
202             log.info("AddPending: local = " +
203                      (localAddr == null ? "null" : localAddr.toString()) +
204                      "; remote = " +
205                      (remoteAddr == null ? "null" : remoteAddr.toString()) +
206                      "; localTran is " + (localTran == null ? "null" :
207                                           localTran.getInfo().toString())+".");
208         }
209
210         if (remoteAddr != null) {
211             try {
212                 impl = TransportProvider.createImpl(localTran.getInfo().
213                                                     getTransportInfoType(),
214                                                     channel);
215                 impl.setListener(listener);
216                 pendingTable.put(remoteAddr, impl);
217             } catch (IOException JavaDoc e) {
218                 // TODO Auto-generated catch block
219
e.printStackTrace();
220             }
221             return impl;
222         }
223         return null;
224     }
225
226     public synchronized void addPendingTransport(TransportImpl impl) {
227         pendingTable.put(impl.getRemoteSocketAddress(), impl);
228     }
229
230     public synchronized TransportImpl
231         removePendingTransport(SocketAddress JavaDoc addr) {
232         return (TransportImpl) pendingTable.remove(addr);
233     }
234
235     /**
236      * This method is called when a pending transport receives an ID
237      * from the other side. It tries to find the premanent transport
238      * object which should own the pending transport's channel. A
239      * permanent transport which already holds a channel is an
240      * indication of a race condition - two agents tried to connect to
241      * each other at the same time. The race condition is handled:
242      * both sides will close the same channel. Additionally, an ID
243      * message will be sent to other side if necessary, i.e. if the
244      * pending tranport's channel is the one which survives.
245      *
246      * @param addr the pending transport's remote address
247      * @param remoteName the remote agent's name
248      * @param myName my agent's name (in case there's a need to send an ID)
249      * @return boolean - if the association succeeded.
250      */

251     public synchronized boolean associatePending(SocketAddress JavaDoc addr,
252                                                  String JavaDoc remoteName,
253                                                  String JavaDoc myName, boolean initId)
254     {
255         TransportImpl pending = removePendingTransport(addr);
256         Set transports = getTransports(remoteName);
257
258         if (transports != null) {
259             Iterator i = transports.iterator();
260             while (i.hasNext()) {
261                 Transport t = (Transport) i.next();
262                 TransportType type = t.getInfo().getTransportInfoType();
263                 if (type.equals(pending.getType())) {
264                     t.mergeImpl(pending, initId);
265                     return true;
266                 }
267             }
268         }
269         pending.shutdown();
270         return false;
271     }
272
273     public synchronized boolean isPending(SocketAddress JavaDoc addr) {
274         return pendingTable.containsKey(addr);
275     }
276
277     public synchronized Set getTransports(String JavaDoc agent) {
278         return (Set) agentTable.get(agent);
279     }
280
281     public synchronized Transport getTransport(SocketAddress JavaDoc addr) {
282         return (Transport) addressTable.get(addr);
283     }
284     
285     public synchronized Transport getUdpTransport(InetAddress JavaDoc addr) {
286         return (Transport) udpAddressTable.get(addr);
287     }
288
289     public synchronized SocketAddress JavaDoc getLocalAddress(String JavaDoc myName,
290                                                       Transport t) {
291         Set transports = getTransports(myName);
292         Iterator i = transports.iterator();
293         SocketAddress JavaDoc addr = null;
294
295         if (i.hasNext()) {
296             addr = ((Transport) i.next()).getInfo().getSocketAddress();
297         }
298
299         return addr;
300     }
301
302     public synchronized boolean isLocalType(TransportType type) {
303 // if (type == TransportType.CDP && !localUDPTable.isEmpty()) {
304
// return true;
305
// }
306

307         if (type == TransportType.MWB) {
308             return true;
309         }
310
311         Iterator i = this.localTCPTable.values().iterator();
312         while (i.hasNext()) {
313             if (((TransportTypeable) i.next()).getTransportType() == type) {
314                 return true;
315             }
316         }
317
318         return false;
319     }
320
321     public synchronized boolean exists(String JavaDoc agent, TransportInfo info,
322                                        boolean indirect)
323     {
324         if (indirect && this.indirectTable.get(agent) != null) {
325             return true;
326         }
327         if (!indirect) {
328             Transport t =
329                 (Transport) this.addressTable.get(info.getSocketAddress());
330             if (t != null && t.getRemoteAgentName().equals(agent)) {
331                 return true;
332             }
333         }
334         return false;
335     }
336
337     /**
338      * this is used (indirectly) by the CMCCommand "get_connections".
339      *
340      * @return a List of org.mr.api.console.gui.Link
341      * objects, each one representing a connected socket.
342      */

343     public List getConnections(String JavaDoc myName) {
344         List result = new LinkedList();
345         String JavaDoc remoteIP, localIP;
346         HashSet copy = new HashSet();
347         synchronized(agentTable){
348             
349             copy.addAll( this.agentTable.keySet()) ;
350         }
351         Iterator i = copy.iterator();
352         while (i.hasNext()) {
353             String JavaDoc agent = (String JavaDoc) i.next();
354             Iterator ii = getTransports(agent).iterator();
355             while (ii.hasNext()) {
356                 Transport t = (Transport) ii.next();
357                 Iterator iii = t.getConnectedImpls().iterator();
358                 while (iii.hasNext()) {
359                     TransportImpl impl = (TransportImpl) iii.next();
360                     InetSocketAddress JavaDoc local = impl.getLocalSocketAddress();
361                     InetSocketAddress JavaDoc remote = impl.getRemoteSocketAddress();
362                     if (local == null || remote == null) {
363                         continue;
364                     }
365                     Link link =
366                         new Link(t.getInfo().getTransportInfoType().toString(),
367                                  myName, local.getAddress().getHostAddress(),
368                                  local.getPort(), agent,
369                                  remote.getAddress().getHostAddress(),
370                                  remote.getPort(),t.getTotalMessages(),
371                                  t.getTotalBytes(),t.getFiveMinMessages(),
372                                  t.getFiveMinBytes());
373                     result.add(link);
374                 }
375             }
376         }
377
378         return result;
379     }
380
381     public synchronized boolean isAccessible(String JavaDoc agent) {
382         Boolean JavaDoc cacheVal = (Boolean JavaDoc) this.agentAccessibleCache.get(agent);
383         boolean retVal = false;
384
385         if (cacheVal == null) {
386             Set transports = (Set) this.agentTable.get(agent);
387             if(transports != null){
388                 Iterator i = transports.iterator();
389                 while (i.hasNext()) {
390                     Transport t = (Transport) i.next();
391                     if (isLocalType(t.getInfo().getTransportInfoType())) {
392                         retVal = true;
393                         break;
394                     }
395                 }
396                 this.agentAccessibleCache.put(agent, new Boolean JavaDoc(retVal));
397             }
398                 
399         } else {
400             retVal = cacheVal.booleanValue();
401         }
402
403         return retVal;
404     }
405
406     public synchronized InetAddress JavaDoc getLocalInterface(String JavaDoc agent) {
407         Set transports = (Set) this.agentTable.get(agent);
408         if (transports != null) {
409             Iterator i = transports.iterator();
410             while (i.hasNext()) {
411                 Transport t = (Transport) i.next();
412                 InetSocketAddress JavaDoc saddr = t.getLocalSocketAddress();
413                 if (saddr != null) {
414                     return saddr.getAddress();
415                 }
416             }
417         }
418         return null;
419     }
420 } // TransportTable
421
Popular Tags