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

Quick Search    Search Deep

Source code: net/jxta/ext/config/Util.java


1   /*
2    *  Copyright (c) 2001 Sun Microsystems, Inc.  All rights
3    *  reserved.
4    *
5    *  Redistribution and use in source and binary forms, with or without
6    *  modification, are permitted provided that the following conditions
7    *  are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright
10   *  notice, this list of conditions and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright
13   *  notice, this list of conditions and the following disclaimer in
14   *  the documentation and/or other materials provided with the
15   *  distribution.
16   *
17   *  3. The end-user documentation included with the redistribution,
18   *  if any, must include the following acknowledgment:
19   *  "This product includes software developed by the
20   *  Sun Microsystems, Inc. for Project JXTA."
21   *  Alternately, this acknowledgment may appear in the software itself,
22   *  if and wherever such third-party acknowledgments normally appear.
23   *
24   *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
25   *  must not be used to endorse or promote products derived from this
26   *  software without prior written permission. For written
27   *  permission, please contact Project JXTA at http://www.jxta.org.
28   *
29   *  5. Products derived from this software may not be called "JXTA",
30   *  nor may "JXTA" appear in their name, without prior written
31   *  permission of Sun.
32   *
33   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35   *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36   *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
37   *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38   *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39   *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
40   *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41   *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42   *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43   *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44   *  SUCH DAMAGE.
45   *  ====================================================================
46   *
47   *  This software consists of voluntary contributions made by many
48   *  individuals on behalf of Project JXTA.  For more
49   *  information on Project JXTA, please see
50   *  <http://www.jxta.org/>.
51   *
52   *  This license is based on the BSD license adopted by the Apache Foundation.
53   *
54   *  $Id: Util.java,v 1.19 2004/11/30 22:42:11 gonzo Exp $
55   */
56  package net.jxta.ext.config;
57  
58  import java.io.IOException;
59  import java.net.BindException;
60  import java.net.InetAddress;
61  import java.net.ServerSocket;
62  import java.net.UnknownHostException;
63  import java.net.URI;
64  import java.net.URISyntaxException;
65  import java.util.Iterator;
66  
67  import java.io.File;
68  import java.io.FileNotFoundException;
69  import java.io.FileReader;
70  
71  import org.apache.log4j.Level;
72  import org.apache.log4j.Logger;
73  
74  /**
75   *  Description of the Class
76   *
77   * @author    james todd [gonzo at jxta dot org]
78   * @version     $Id: Util.java,v 1.19 2004/11/30 22:42:11 gonzo Exp $
79   */
80  
81  public class Util {
82  
83      private final static String MACRO_PREFIX = "${";
84      private final static String MACRO_POSTFIX = "}";
85      private final static String MACRO_ESCAPE = "\\";
86      private final static String NEW_LINE = "\n";
87      private final static String EMPTY_STRING = "";
88      private final static Logger LOG = Logger.getLogger(Util.class.getName());
89  
90  
91      /**
92       *  Description of the Method
93       *
94       * @param  s  Description of the Parameter
95       * @return    Description of the Return Value
96       */
97      public static String expand(String s) {
98          StringBuffer sb = null;
99  
100         if (s != null) {
101             sb = new StringBuffer(s);
102             int i = -1;
103             int j = -1;
104 
105             while ((i = sb.indexOf(MACRO_PREFIX)) > -1 &&
106                    (i - MACRO_ESCAPE.length() < 0 ||
107                     (i - MACRO_ESCAPE.length() >= 0 &&
108                      !sb.substring(i - MACRO_ESCAPE.length(), i).equals(MACRO_ESCAPE))) &&
109                    (j = sb.indexOf(MACRO_POSTFIX, i + MACRO_PREFIX.length())) > -1) {
110                 String p = expand(sb.substring(i + MACRO_PREFIX.length(), j));
111 
112                 sb.replace(i, j + MACRO_POSTFIX.length(), System.getProperty(p, ""));
113             }
114         }
115 
116         return sb != null ? sb.toString() : null;
117     }
118 
119 
120     /**
121      *  Gets the local address.
122      *
123      * @return    The local address
124      */
125     public static String getLocalHost() {
126         String s = null;
127 
128         try {
129             s = InetAddress.getLocalHost().getHostAddress();
130         } catch (UnknownHostException uhe) {
131             if (LOG.isEnabledFor(Level.ERROR)) {
132                 LOG.error("can't resolve local host", uhe);
133             }
134         }
135 
136         return s;
137     }
138 
139     /**
140      *  Description of the Method
141      *
142      * @param  address  Description of the Parameter
143      * @return          Description of the Return Value
144      */
145     public static String validateAddress(URI address) {
146         return validateAddress(address, (boolean)true);
147     }
148 
149     public static String validateAddress(URI address, int minimumPort) {
150         return validateAddress(address, (String)null, minimumPort);
151     }
152 
153     /**
154      *  Description of the Method
155      *
156      * @param  address      Description of the Parameter
157      * @param  requireHost  Description of the Parameter
158      * @return              Description of the Return Value
159      */
160     public static String validateAddress(URI address, boolean requireHost) {
161         return validateAddress(address, (String)null, requireHost);
162     }
163 
164 
165     /**
166      *  Validate address against the provided scheme.
167      *
168      * @param  address  Description of the Parameter
169      * @param  scheme   scheme
170      * @return          Validation state
171      */
172     public static String validateAddress(URI address, String scheme) {
173         return validateAddress(address, scheme, (boolean)false);
174     }
175 
176 
177     /**
178      *  Validate address against the provided scheme and host requirement.
179      *
180      * @param  address      addresss
181      * @param  scheme       scheme
182      * @param  requireHost  Description of the Parameter
183      * @return              Validation state
184      */
185     public static String validateAddress(URI address, String scheme, boolean requireHost) {
186         return validateAddress(address, scheme, requireHost, Default.MINIMUM_DYNAMIC_PORT);
187     }
188 
189 
190     /**
191      *  Validate address against the provided scheme and host requirement.
192      *
193      * @param  address      addresss
194      * @param  scheme       scheme
195      * @param  minimumPort  minimum port
196      * @return              Validation state
197      */
198     public static String validateAddress(URI address, String scheme, int minimumPort) {
199         return validateAddress(address, scheme, (boolean)false, minimumPort);
200     }
201 
202 
203     /**
204      *  Validate address against the provided scheme and host requirement.
205      *
206      * @param  address      addresss
207      * @param  scheme       scheme
208      * @param  requireHost  Description of the Parameter
209      * @param  minimumPort  minimum port
210      * @return              Validation state
211      */
212     public static String validateAddress(URI address, String scheme, boolean requireHost,
213                                          int minimumPort) {
214         StringBuffer b = new StringBuffer();
215 
216         if (address != null) {
217             if (scheme != null &&
218                 !address.getScheme().equalsIgnoreCase(scheme)) {
219                 b.append((b.length() > 0 ? NEW_LINE : EMPTY_STRING) + "invalid scheme: " +
220                          scheme);
221             }
222 
223             if (requireHost) {
224                 String h = address.getHost();
225 
226                 if (h == null ||
227                     h.trim().length() == 0) {
228                     b.append((b.length() > 0 ? NEW_LINE : EMPTY_STRING) + "invalid host: " + h);
229                 }
230 
231                 // xxx: don't validate the adress for now.
232                 //         it would be nice to validate fqn addresses (eg www.jxta.org) and ip addresses
233                 //         (eg 123.123.123.123) alike without requiring resolution.
234                 /*
235                 if (h != null &&
236                     Protocol.isValid(address.getScheme())) {
237                     InetAddress ia = null;
238 
239                     try {
240                         ia = InetAddress.getByName(h);
241                     } catch (UnknownHostException uhe) {
242                         if (LOG.isEnabledFor(Level.ERROR)) {
243                             LOG.error("invalid address", uhe);
244                         }
245                     }
246 
247                     if (ia == null) {
248                         b.append((b.length() > 0 ? NEW_LINE : EMPTY_STRING) + "invalid host: " + h);
249                     }
250             }
251                 */
252 
253                 if (address.getPort() < minimumPort ||
254                     address.getPort() > Default.MAXIMUM_PORT) {
255                     b.append((b.length() > 0 ? NEW_LINE : EMPTY_STRING) + "invalid port: " + address.getPort());
256                 }
257             }
258         } else {
259             b.append((b.length() > 0 ? NEW_LINE : EMPTY_STRING) + "null address");
260         }
261 
262         return b.toString();
263     }
264 
265 
266     /**
267      *  Description of the Method
268      *
269      * @param  address  Description of the Parameter
270      * @return          Description of the Return Value
271      */
272     public static URI normalize(Address address) {
273         return normalize(address, true);
274     }
275 
276     /**
277      *  Description of the Method
278      *
279      * @param  address  Description of the Parameter
280      * @param portScan  port scan
281      * @return          Description of the Return Value
282      */
283 
284     public static URI normalize(Address address, boolean portScan) {
285         URI u = address != null ? address.getAddress() : null;
286 
287         return normalize(address, portScan,
288                          model(u != null ? u.getScheme() : null));
289     }
290 
291     /**
292      *  Address normalizer.
293      *
294      * @param  address  base address
295      * @param  portScan port scan
296      * @param  model    model address
297      * @return          Resultant address
298      */
299     public static URI normalize(Address address, boolean portScan, URI model) {
300         URI u = address != null ? address.getAddress() : null;
301 
302         if (u != null) {
303             String s = u.getScheme();
304             String h = u.getHost();
305             int p = u.getPort();
306 
307             if (model != null) {
308                 if (s == null ||
309                     s.trim().length() == 0) {
310                     s = model.getScheme();
311                 }
312 
313                 if (h == null ||
314                     h.trim().length() == 0) {
315                     h = model.getHost();
316                 }
317 
318                 if (p == Default.INVALID_PORT) {
319                     p = model.getPort();
320                 }
321             }
322 
323             try {
324                 address.setAddress(new URI(u.getScheme(), u.getUserInfo(),
325                                            h, p, u.getPath(), u.getQuery(),
326                                            u.getFragment()));
327 
328                 u = new URI(u.getScheme(), u.getUserInfo(), h,
329                             portScan ? getNextAvailablePort(address, p) : p,
330                             u.getPath(), u.getQuery(), u.getFragment());
331             } catch (URISyntaxException use) {
332                 if (LOG.isEnabledFor(Level.ERROR)) {
333                     LOG.error("invalid transformation", use);
334                 }
335             }
336         }
337 
338         return u;
339     }
340 
341 
342     /**
343      *  Description of the Method
344      *
345      * @param  scheme  Description of the Parameter
346      * @param  host    Description of the Parameter
347      * @param  port    Description of the Parameter
348      * @return         Description of the Return Value
349      */
350     public static URI toURI(String scheme, String host, int port) {
351         URI u = null;
352 
353         try {
354             u = new URI(scheme, EMPTY_STRING,
355                         host == null || host.trim().length() == 0 ? getLocalHost() : host,
356                         port, EMPTY_STRING, EMPTY_STRING, EMPTY_STRING);
357         } catch (URISyntaxException use) {
358             if (LOG.isEnabledFor(Level.ERROR)) {
359                 LOG.error("invalid transformation", use);
360             }
361         }
362 
363         return u;
364     }
365 
366 
367     /**
368      *  Description of the Method
369      *
370      * @param  scheme  Description of the Parameter
371      * @return         Description of the Return Value
372      */
373     public static URI model(String scheme) {
374         return model(scheme, Default.INVALID_PORT);
375     }
376 
377     public static URI model(String scheme, int port) {
378         URI u = null;
379 
380         if (Protocol.TCP.equalsIgnoreCase(scheme)) {
381             u = toURI(Default.ANY_TCP_ADDRESS.getScheme(), null,
382                       port != Default.INVALID_PORT ?
383                       port : Default.TCP_PORT);
384         } else if (Protocol.HTTP.equalsIgnoreCase(scheme)) {
385             u = toURI(Default.ANY_HTTP_ADDRESS.getScheme(), null,
386                       port != Default.INVALID_PORT ?
387                       port : Default.HTTP_PORT);
388         } else if (Protocol.UDP.equalsIgnoreCase(scheme)) {
389             u = toURI(Default.ANY_UDP_ADDRESS.getScheme(),
390                       Default.MULTICAST_ADDRESS.getHost(),
391                       port != Default.INVALID_PORT ?
392                       port : Default.MULTICAST_PORT);
393         }
394 
395         return u;
396     }
397 
398     /**
399      *  Checks for the specified port availability.
400      *
401      * @param  address  target system address
402      * @param  port     target port
403      * @return          The availability indicator
404      */
405     public static boolean isPortAvailable(InetAddress address, int port) {
406         ServerSocket ss = getServerSocket(address, port);
407         boolean isAvailable = ss != null;
408 
409         if (ss != null) {
410             try {
411                 ss.close();
412             } catch (IOException ioe) {}
413         }
414 
415         ss = null;
416 
417         return isAvailable;
418     }
419 
420     public static ServerSocket getServerSocket(InetAddress address, int port) {
421         ServerSocket ss = null;
422 
423         try {
424             ss = new ServerSocket(port, 0,
425                                   address != null &&
426                                   ! address.getHostAddress().equals(Env.ALL_ADDRESSES.getHostAddress()) ?
427                                   address : null);
428         } catch (BindException be) {}
429         catch (IOException ioe) {}
430 
431         return ss;
432     }
433 
434     public static String getProxyFromUserAgent() {
435         String p = null;
436 
437         return p;
438     }
439 
440     public static boolean isNonRoutable(URI u) {
441         boolean isNonRoutable = false;
442         String a = u != null ? u.getHost() : null;
443 
444         if (a != null) {
445             for (Iterator r = Env.NON_ROUTABLE_ADDRESSES.iterator();
446                  ! isNonRoutable && r.hasNext(); ) {
447                 if (a.startsWith((String)r.next())) {
448                     isNonRoutable = true;
449                 }
450             }
451         }
452 
453         return isNonRoutable;
454     }
455 
456     public static boolean isMulticast(URI u) {
457         String h = u != null ? u.getHost() : null;
458         InetAddress ia =  null;
459 
460         if (h != null) {
461             try {
462                 ia = InetAddress.getByAddress(h, inetAddressToBytes(h));
463             } catch (UnknownHostException uhe) {
464                 if (LOG.isEnabledFor(Level.ERROR)) {
465                     LOG.error("invalid address", uhe);
466                 }
467             }
468         }
469 
470         return ia != null ? ia.isMulticastAddress() : false;
471     }
472 
473     public static byte[] inetAddressToBytes(String ipAddr) {
474         byte[] bytes = new byte[4];
475         int bit = 0;
476 
477         for(int i = 0; i < ipAddr.length(); i++) {
478             char c = ipAddr.charAt(i);
479 
480             switch(c) {
481             case '.':
482                 bit++;
483                 break;
484             default:
485                 bytes[bit] = (byte)(bytes[bit]*10 + Character.digit(c, 10));
486                 break;
487             }
488         }
489 
490         return bytes;
491     }
492 
493     /**
494      *  Gets the nextAvailablePort attribute of the Configurator object
495      *
496      * @param  a            Description of the Parameter
497      * @param  defaultPort  Description of the Parameter
498      * @return              The nextAvailablePort value
499      */
500     private static int getNextAvailablePort(Address a, int defaultPort) {
501         URI u = a != null ? a.getAddress() : null;
502         String h = u != null ? u.getHost() : null;
503         int p = u != null ? u.getPort() : Default.INVALID_PORT;
504         int port = p != Default.INVALID_PORT ? p : defaultPort;
505         int pr = a != null ? a.getPortRange() : Default.PORT_RANGE;
506         InetAddress ia = null;
507 
508         if (h != null) {
509             try {
510                 ia = InetAddress.getByAddress(h, inetAddressToBytes(h));
511             } catch (UnknownHostException uhe) {
512                 if (LOG.isEnabledFor(Level.ERROR)) {
513                     LOG.error("invalid address", uhe);
514                 }
515             }
516 
517             if (ia != null &&
518                 p != Default.INVALID_PORT) {
519                 for (int i = p; i <= p + pr; i++) {
520                     if (isPortAvailable(ia, i)) {
521                         port = i;
522 
523                         break;
524                     }
525                 }
526             }
527         }
528 
529         return port;
530     }
531 }