KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SOFA > SOFAnet > Repository > NodeInfo


1 /*
2  * NodeInfo.java
3  *
4  * Created on 25. listopad 2003, 19:05
5  */

6
7 package SOFA.SOFAnet.Repository;
8
9 import java.net.*;
10 import SOFA.Util.VMProperties;
11
12 /**
13  * Representation of name of node.
14  *
15  * @author Ladislav Sobr
16  */

17 public class NodeInfo
18 {
19   private String JavaDoc name;
20   private InetAddress address;
21   private int port;
22   
23   public static class InvalidNodeNameException extends SOFA.SOFAnode.SOFAException
24   {
25     public InvalidNodeNameException(String JavaDoc message)
26     {
27       super(message);
28     }
29
30     public InvalidNodeNameException(String JavaDoc message, Throwable JavaDoc cause)
31     {
32       super(message, cause);
33     }
34
35     public InvalidNodeNameException(Throwable JavaDoc cause)
36     {
37       super(cause);
38     }
39   }
40   
41   /**
42    * Returns representation of node "localhost"
43    */

44   public static NodeInfo getLocalhost()
45   {
46     String JavaDoc localhost;
47     try
48     {
49       localhost = InetAddress.getLocalHost().getHostName();
50     }
51     catch (UnknownHostException e)
52     {
53       localhost = "localhost";
54     }
55     
56     NodeInfo nodeInfo = new NodeInfo();
57     
58     try
59     {
60       nodeInfo.setNodeName(localhost);
61     }
62     catch (InvalidNodeNameException e)
63     {
64     }
65     
66     return nodeInfo;
67   }
68     
69   /** Returns node name of local node */
70   public static String JavaDoc getLocalNodeName()
71   {
72     String JavaDoc nodeName = System.getProperty(VMProperties.NODE_NAME).trim();
73     if (!nodeName.toLowerCase().startsWith("sofa://")) nodeName = "sofa://" + nodeName;
74     return nodeName;
75   }
76   
77   /** Creates a new instance of NodeInfo */
78   public NodeInfo()
79   {
80     port = -1;
81   }
82   
83   /**
84    * Sets name of node.
85    * <p>
86    * Node name should be in format (text in [] is optional):
87    * <p>
88    * &nbsp;&nbsp;&nbsp;&nbsp; [sofa://]ip_address_or_host_name[:port]
89    *
90    * @param nodeName name of node
91    */

92   public void setNodeName(String JavaDoc nodeName) throws InvalidNodeNameException
93   {
94     name = nodeName;
95     
96     nodeName = nodeName.trim();
97     if (nodeName.toLowerCase().startsWith("sofa://"))
98         nodeName = nodeName.substring(7).trim();
99
100     if (nodeName.length() <= 0) throw new InvalidNodeNameException("Empty node name");
101       
102     port = -1;
103
104     int i = nodeName.indexOf(':');
105
106     if (i != -1)
107     {
108       try
109       {
110         port = Integer.parseInt(nodeName.substring(i + 1));
111       }
112       catch (NumberFormatException JavaDoc e)
113       {
114         throw new NodeInfo.InvalidNodeNameException("Invalid node name format (cannot read port)", e);
115       }
116       nodeName = nodeName.substring(0, i);
117     }
118
119     try
120     {
121       address = InetAddress.getByName(nodeName);
122     }
123     catch (UnknownHostException e)
124     {
125       throw new NodeInfo.InvalidNodeNameException("Unknown host '" + nodeName + "'", e);
126     }
127   }
128   
129   /**
130    * Tests wheter internal node name can pass specified pattern.
131    * <p>
132    * Pattern can be in one of following formats (text in [] is optional):
133    * <ul>
134    * <li>a) concrete host (also port can be present)
135    * <ul>
136    * <li> [sofa://]ip_address_or_host_name[:port]
137    * <li> Example:
138    * <ul>
139    * <li> sofa://192.168.0.1
140    * <li> nenya:1000
141    * </ul>
142    * </ul>
143    * <li>b) domain (also port can be present)
144    * <ul>
145    * <li> [sofa://]domain_name[:port]
146    * <li> Example:
147    * <ul>
148    * <li>sofa://cuni.cz
149    * <li>mff.cuni.cz:1000
150    * </ul>
151    * </ul>
152    * <li>c) part_of_IPv4_address/number_of_mask_bits[:port]
153    * <ul>
154    * <li> Example:
155    * <ul>
156    * <li>192.168.20/22:2000
157    * </ul>
158    * <li> Mask bits can be ommited:
159    * <ul>
160    * <li>192.168.0.1:2000
161    * <li>in this case mask bits are considered to be 32 (full IPv4 address)
162    * </ul>
163    * </ul>
164    * <li>d) [sofa://]* &nbsp;&nbsp; - asterix means any host
165    * </ul>
166    * <p>
167    * If "port" is present (in any formats), the node match the pattern only
168    * if the same port is specified in the node.
169    *
170    * @param nodeNamePattern pattern to test
171    * @return true, if the internal node name matches the pattern
172    */

173   
174   public boolean matchPattern(String JavaDoc nodeNamePattern) throws InvalidNodeNameException
175   {
176     if (address == null) return false;
177     
178     //remove possible leading string sofa://
179

180     nodeNamePattern = nodeNamePattern.trim();
181     if (nodeNamePattern.toLowerCase().startsWith("sofa://"))
182         nodeNamePattern = nodeNamePattern.substring(7).trim();
183
184     if (nodeNamePattern.compareTo("*") == 0) return true;
185
186     //try to find port part of pattern and compare it to node port
187

188     int i = nodeNamePattern.indexOf(':');
189
190     if (i != -1)
191     {
192       int patternPort = -1;
193       try
194       {
195         patternPort = Integer.parseInt(nodeNamePattern.substring(i + 1));
196       }
197       catch (NumberFormatException JavaDoc e)
198       {
199         throw new NodeInfo.InvalidNodeNameException("Invalid node name pattern (cannot read port)", e);
200       }
201
202       //check equality or pattern port and node port
203
if (patternPort != port) return false;
204       
205       //remove port from pattern
206
nodeNamePattern = nodeNamePattern.substring(0, i);
207     }
208
209
210     //try to check this format: part_of_ip_address/number_of_mask_bits:port
211
//example: 192.168.20/22:2000
212

213     i = nodeNamePattern.indexOf('/');
214     
215     if (i != -1) //format found
216
{
217       byte [] ipAddr = address.getAddress();
218       if (ipAddr.length != 4) return false; //we support just IPv4 addresses
219

220       int maskBits = 32;
221       
222       try
223       {
224         maskBits = Integer.parseInt(nodeNamePattern.substring(i + 1));
225       }
226       catch (NumberFormatException JavaDoc e)
227       {
228         throw new NodeInfo.InvalidNodeNameException("Invalid node name pattern (cannot read number of mask bits)", e);
229       }
230       nodeNamePattern = nodeNamePattern.substring(0, i);
231     
232       String JavaDoc [] ipParts = nodeNamePattern.split("\\.");
233       if (ipParts.length > 4)
234           throw new NodeInfo.InvalidNodeNameException("Invalid node name pattern (invalid \"IP address\" part)");
235
236       for (i = 0; i < ipParts.length; i++)
237       {
238         int number;
239         int bits = 0;
240         try
241         {
242           number = Integer.parseInt(ipParts[i]);
243         }
244         catch (NumberFormatException JavaDoc e)
245         {
246           throw new NodeInfo.InvalidNodeNameException("Invalid node name pattern (cannot read \"IP address\" part)", e);
247         }
248
249         if (maskBits >= 8) bits = 8;
250         else bits = maskBits;
251         maskBits -= bits;
252         if (bits == 0) return true;
253
254         int mask = 256 - (1 << (8 - bits));
255         if ((number & mask) != (ipAddr[i] & mask)) return false;
256       }
257
258       if (maskBits > 0)
259           throw new NodeInfo.InvalidNodeNameException("Invalid node name pattern (incomplete \"IP address\" part or to many mask bits)");
260       
261       return true;
262     }
263
264     //try to compare domains of node and pattern
265
String JavaDoc nodeHost = address.getCanonicalHostName();
266     if (nodeHost.endsWith("." + nodeNamePattern)) return true;
267     
268     //try to compare IP addresses of pattern and node
269
try
270     {
271       InetAddress addr = InetAddress.getByName(nodeNamePattern);
272       if (addr.equals(address)) return true;
273     }
274     catch (UnknownHostException e)
275     {
276     }
277
278     return false;
279   }
280   
281   /**
282    * Tests whether internal node name has same host as the specified one.
283    * @param host host to match
284    * @return true if the internal node name has same host as the specified one.
285    */

286   public boolean isSameHost(String JavaDoc host) throws InvalidNodeNameException
287   {
288     if (address == null) throw new NodeInfo.InvalidNodeNameException("Empty address");
289     
290     try
291     {
292       InetAddress addr = InetAddress.getByName(host);
293       if (addr.equals(address)) return true;
294       else return false;
295     }
296     catch (UnknownHostException e)
297     {
298       throw new NodeInfo.InvalidNodeNameException(e.getMessage(), e);
299     }
300   }
301     
302   public String JavaDoc toString()
303   {
304 // if (address == null) return "";
305
// else
306
// {
307
// String s = "sofa://" + address.getCanonicalHostName();
308
// if (port != -1) s += ":" + port;
309
// return s;
310
// }
311
return name;
312   }
313   
314   public String JavaDoc getName()
315   {
316     return name;
317   }
318   
319   public InetAddress getAddress()
320   {
321     return address;
322   }
323   
324   public int getPort()
325   {
326     return port;
327   }
328   
329   public String JavaDoc getAddressAndPort()
330   {
331     if (address == null) return "";
332     if (port == -1) return address.getHostAddress();
333     else return address.getHostAddress() + ":" + port;
334   }
335 }
336
Popular Tags