/[classpath]/classpath/java/net/URL.java
ViewVC logotype

Diff of /classpath/java/net/URL.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by mark, Fri Oct 18 20:40:50 2002 UTC revision 1.10 by mark, Fri Nov 22 02:42:26 2002 UTC
# Line 1  Line 1 
1  /* URL.java -- Uniform Resource Locator Class  /* URL.java -- Uniform Resource Locator Class
2     Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 43  import java.io.IOException; Line 43  import java.io.IOException;
43  import java.io.Serializable;  import java.io.Serializable;
44  import java.io.ObjectInputStream;  import java.io.ObjectInputStream;
45  import java.io.ObjectOutputStream;  import java.io.ObjectOutputStream;
 import java.util.StringTokenizer;  
46  import java.util.Hashtable;  import java.util.Hashtable;
47    import java.util.StringTokenizer;
48    
49    
50    /*
51     * Written using on-line Java Platform 1.2 API Specification, as well
52     * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
53     * Status:  Believed complete and correct.
54     */
55    
56  /**  /**
57    * This final class represents an Internet Uniform Resource Locator (URL).    * This final class represents an Internet Uniform Resource Locator (URL).
# Line 105  import java.util.Hashtable; Line 112  import java.util.Hashtable;
112    * done, then the above information is superseded and the behavior of this    * done, then the above information is superseded and the behavior of this
113    * class in loading protocol handlers is dependent on that factory.    * class in loading protocol handlers is dependent on that factory.
114    *    *
   * @version 0.5  
   *  
115    * @author Aaron M. Renn (arenn@urbanophile.com)    * @author Aaron M. Renn (arenn@urbanophile.com)
116      * @author Warren Levy <warrenl@cygnus.com>
117    *    *
118    * @see URLStreamHandler    * @see URLStreamHandler
119    */    */
120  public final class URL implements Serializable  public final class URL implements Serializable
121  {  {
122      /**
123       * The name of the protocol for this URL.
124       * The protocol is always stored in lower case.
125       */
126      private String protocol;
127    
128  /*************************************************************************/    /**
129       * The "authority" portion of the URL.
130       */
131      private String authority;
132    
133  /*    /**
134   * Class Variables     * The hostname or IP address of this protocol.
135   */     * This includes a possible user. For example <code>joe@some.host.net</code>.
136       */
137      private String host;
138    
139    private static final long serialVersionUID = -7627629688361524110L;    /**
140       * The port number of this protocol or -1 if the port number used is
141       * the default for this protocol.
142       */
143      private int port = -1;        // Initialize for constructor using context.
144    
145  /**    /**
146    * If an application installs in own protocol handler factory, this is     * The "file" portion of the URL. It is defined as <code>path[?query]</code>.
147    * where we keep track of it.     */
148    */    private String file;
149  private static URLStreamHandlerFactory factory;  
150      /**
151       * The anchor portion of the URL.
152       */
153      private String ref;
154    
155      /**
156       * This is the hashCode for this URL
157       */
158      private int hashCode = 0;
159    
160      /**
161       * The protocol handler in use for this URL
162       */
163      transient private URLStreamHandler handler;
164    
165      /**
166       * This a table where we cache protocol handlers to avoid the overhead
167       * of looking them up each time.
168       */
169      private static Hashtable handlers = new Hashtable();
170    
171      /**
172       * If an application installs its own protocol handler factory, this is
173       * where we keep track of it.
174       */
175      private static URLStreamHandlerFactory factory;
176    
177      private static final long serialVersionUID = -7627629688361524110L;
178    
179  /**  /**
180    * This a table where we cache protocol handlers to avoid the overhead    * This a table where we cache protocol handlers to avoid the overhead
# Line 140  private static Hashtable ph_cache = new Line 188  private static Hashtable ph_cache = new
188  private static boolean cache_handlers;  private static boolean cache_handlers;
189    
190  /**  /**
191    * The search path of packages to search for protocol handlers in    * The search path of packages to search for protocol handlers in.
192    */    */
193  private static String ph_search_path;  private static String ph_search_path;
194    
# Line 161  static Line 209  static
209      ph_search_path = "gnu.java.net.protocol";      ph_search_path = "gnu.java.net.protocol";
210  }  }
211    
 /*************************************************************************/  
   
 /*  
  * Instance Variables  
  */  
   
 /**  
   * The name of the protocol for this URL  
   */  
 private String protocol;  
   
 /**  
   * The hostname or IP address of this protocol  
   */  
 private String host;  
   
 /**  
   * The port number of this protocol or -1 if the port number used is  
   * the default for this protocol.  
   */  
 private int port = -1;  
   
 /**  
   * The "file" portion of the URL  
   */  
 private String file;  
   
   /**  
    * The "authority" portion of the URL  
    */  
   private String authority;  
   
 /**  
   * The anchor portion of the URL  
   */  
 private String ref;  
   
   private transient String userInfo;  
   
 /**  
   * The protocol handler in use for this URL  
   */  
 private transient URLStreamHandler ph;  
   
 /**  
   * This is the hashCode for this URL  
   */  
 private int hashCode;  
   
 /*************************************************************************/  
   
 /*  
  * Static Methods  
  */  
   
 /**  
   * Sets the URLStreamHandlerFactory for this class.  This factory is  
   * responsible for returning the appropriate protocol handler for  
   * a given URL.  
   *  
   * @param fac The URLStreamHandlerFactory class to use  
   *  
   * @exception Error If the factory is alread set.  
   */  
 public static synchronized void  
 setURLStreamHandlerFactory(URLStreamHandlerFactory fac)  
 {  
   if (factory == null)  
     factory = fac;  
   else  
     throw new Error("URLStreamHandlerFactory alread set");  
 }  
   
 /*************************************************************************/  
   
212  /**  /**
213    * This internal method is used in two different constructors to load    * This internal method is used in two different constructors to load
214    * a protocol handler for this URL.    * a protocol handler for this URL.
215    *    *
216    * @param The protocol to load a handler for    * @param The protocol to load a handler for
217    *    *
218    * @return A URLStreamHandler for this protocol    * @return A URLStreamHandler for this protocol, or null when not found.
   *  
   * @exception MalformedURLException If the protocol can't be loaded.  
219    */    */
220  private static URLStreamHandler  private static synchronized URLStreamHandler
221  getProtocolHandler(String protocol) throws MalformedURLException  getURLStreamHandler(String protocol)
222  {  {
223    URLStreamHandler ph;    URLStreamHandler ph;
224    
# Line 271  getProtocolHandler(String protocol) thro Line 242  getProtocolHandler(String protocol) thro
242      {      {
243        ph = factory.createURLStreamHandler(protocol);        ph = factory.createURLStreamHandler(protocol);
244        if (ph == null)        if (ph == null)
245          throw new MalformedURLException(protocol);          return null;
246    
247        if (cache_handlers)        if (cache_handlers)
248          ph_cache.put(protocol, ph.getClass());          ph_cache.put(protocol, ph.getClass());
# Line 303  getProtocolHandler(String protocol) thro Line 274  getProtocolHandler(String protocol) thro
274      }      }
275    
276    // Still here, which is bad    // Still here, which is bad
277    throw new MalformedURLException(protocol);    return null;
278  }  }
279    
 /*************************************************************************/  
   
 /*  
  * Constructors  
  */  
280    
281  /**    /**
282    * Constructs a URL and loads a protocol handler for the values passed as     * Constructs a URL and loads a protocol handler for the values passed as
283    * arguments.     * arguments.
284    *     *
285    * @param protocol The protocol for this URL ("http", "ftp", etc)     * @param protocol The protocol for this URL ("http", "ftp", etc)
286    * @param host The hostname or IP address to connect to     * @param host The hostname or IP address to connect to
287    * @param port The port number to use, or -1 to use the protocol's default port     * @param port The port number to use, or -1 to use the protocol's
288    * @param file The "file" portion of the URL.     * default port
289    *     * @param file The "file" portion of the URL.
290    * @exception MalformedURLException If a protocol handler cannot be loaded     *
291    */     * @exception MalformedURLException If a protocol handler cannot be loaded or
292  public     * a parse error occurs.
293  URL(String protocol, String host, int port, String file)     */
294      public URL(String protocol, String host, int port, String file)
295      throws MalformedURLException      throws MalformedURLException
296  {    {
297    this(protocol, host, port, file, null);      this(protocol, host, port, file, null);
298  }    }
   
 /*************************************************************************/  
   
 /**  
   * Constructs a URL and loads a protocol handler for the values passed in  
   * as arugments.  Uses the default port for the protocol.  
   *  
   * @param protocol The protocol for this URL ("http", "ftp", etc)  
   * @param host The hostname or IP address for this URL  
   * @param file The "file" portion of this URL.  
   *  
   * @exception MalformedURLException If a protocol handler cannot be loaded  
   */  
 public  
 URL(String protocol, String host, String file) throws MalformedURLException  
 {  
   this(protocol, host, -1, file, null);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * This method initializes a new instance of <code>URL</code> with the  
   * specified protocol, host, port, and file.  Additionally, this method  
   * allows the caller to specify a protocol handler to use instead of  
   * the default.  If this handler is specified, the caller must have  
   * the "specifyStreamHandler" permission (see <code>NetPermission</code>)  
   * or a <code>SecurityException</code> will be thrown.  
   *  
   * @param protocol The protocol for this URL ("http", "ftp", etc)  
   * @param host The hostname or IP address to connect to  
   * @param port The port number to use, or -1 to use the protocol's default port  
   * @param file The "file" portion of the URL.  
   * @param ph The protocol handler to use with this URL.  
   *  
   * @exception MalformedURLException If no protocol handler can be loaded  
   * for the specified protocol.  
   * @exception SecurityException If the <code>SecurityManager</code> exists  
   * and does not allow the caller to specify its own protocol handler.  
   */  
 public  
 URL(String protocol, String host, int port, String file,  
     URLStreamHandler ph) throws MalformedURLException, SecurityException  
 {  
   this.protocol = protocol.toLowerCase();  
   this.host = host;  
   this.port = port;  
   this.file = file;  
   
   if (ph != null)  
     {  
       SecurityManager sm = System.getSecurityManager();  
       if (sm != null)  
         sm.checkPermission(new NetPermission("specifyStreamHandler"));  
299    
300        this.ph = ph;    /**
301      }     * Constructs a URL and loads a protocol handler for the values passed in
302    else     * as arugments.  Uses the default port for the protocol.
303      {     *
304        this.ph = getProtocolHandler(protocol);     * @param protocol The protocol for this URL ("http", "ftp", etc)
305      }     * @param host The hostname or IP address for this URL
306       * @param file The "file" portion of this URL.
307    hashCode = toString().hashCode();     *
308  }     * @exception MalformedURLException If a protocol handler cannot be loaded or
309       * a parse error occurs.
310       */
311      public URL(String protocol, String host, String file)
312        throws MalformedURLException
313      {
314        this(protocol, host, -1, file, null);
315      }
316    
 /*************************************************************************/  
317    
318  /**    /**
319    * This method parses a String representation of a URL within the     * This method initializes a new instance of <code>URL</code> with the
320    * context of an existing URL.  Principally this means that any fields     * specified protocol, host, port, and file.  Additionally, this method
321    * not present the URL are inheritied from the context URL.  This allows     * allows the caller to specify a protocol handler to use instead of
322    * relative URL's to be easily constructed (***true?***).  If the     * the default.  If this handler is specified, the caller must have
323    * context argument is null, then a complete URL must be specified in the     * the "specifyStreamHandler" permission (see <code>NetPermission</code>)
324    * URL string.  If the protocol parsed out of the URL is different     * or a <code>SecurityException</code> will be thrown.
325    * from the context URL's protocol, then then URL String is also     *
326    * expected to be a complete URL.     * @param protocol The protocol for this URL ("http", "ftp", etc)
327    *     * @param host The hostname or IP address to connect to
328    * @param context The context URL     * @param port The port number to use, or -1 to use the protocol's default
329    * @param url A String representing this URL     * port
330    *     * @param file The "file" portion of the URL.
331    * @exception MalformedURLException If a protocol handler cannot be found     * @param handler The protocol handler to use with this URL.
332    * for the URL cannot be parsed     *
333    */     * @exception MalformedURLException If no protocol handler can be loaded
334  public     * for the specified protocol.
335  URL(URL context, String url) throws MalformedURLException     * @exception SecurityException If the <code>SecurityManager</code> exists
336  {     * and does not allow the caller to specify its own protocol handler.
337    this(context, url, null);     *
338  }     * @since 1.2
339       */
340      public URL(String protocol, String host, int port, String file,
341        URLStreamHandler handler) throws MalformedURLException
342      {
343        if (protocol == null)
344          throw new MalformedURLException("null protocol");
345        this.protocol = protocol.toLowerCase();
346    
347  /*************************************************************************/      if (handler != null)
348          {
349            SecurityManager s = System.getSecurityManager();
350            if (s != null)
351              s.checkPermission (new NetPermission ("specifyStreamHandler"));
352    
353  /**          this.handler = handler;
354    * This method parses a String representation of a URL within the        }
355    * context of an existing URL.  Principally this means that any fields      else
356    * not present the URL are inheritied from the context URL.  This allows        this.handler = getURLStreamHandler(protocol);
   * relative URL's to be easily constructed (***true?***).  If the  
   * context argument is null, then a complete URL must be specified in the  
   * URL string.  If the protocol parsed out of the URL is different  
   * from the context URL's protocol, then then URL String is also  
   * expected to be a complete URL.  
   *  
   * Additionally, this method allows the caller to specify a protocol handler to  
   * use instead of  the default.  If this handler is specified, the caller must  
   * have the "specifyStreamHandler" permission (see <code>NetPermission</code>)  
   * or a <code>SecurityException</code> will be thrown.  
   *  
   * @param context The context URL  
   * @param url A String representing this URL  
   * @param ph The protocol handler for this URL  
   *  
   * @exception MalformedURLException If a protocol handler cannot be found or the URL cannot be parsed  
   * @exception SecurityException If the <code>SecurityManager</code> exists  
   * and does not allow the caller to specify its own protocol handler.  
   */  
 public  
 URL(URL context, String url, URLStreamHandler ph) throws MalformedURLException  
 {  
   int end, start = -1;  
357    
358    int colon_index = url.indexOf(":");      if (this.handler == null)
359    int slash_index = url.indexOf("/");        throw new MalformedURLException (
360                          "Protocol handler not found: " + protocol);
361    
362        this.host = host;
363        this.port = port;
364        this.authority = null;
365    
366    // Find a protocol name in the string if there is one      int hashAt = file.indexOf('#');
367    if (colon_index != -1)      if (hashAt < 0)
     if ((slash_index == -1) ||((slash_index != -1) &&  
                                (colon_index < slash_index)))  
368        {        {
369          protocol = url.substring(0, colon_index);          this.file = file;
370          start = colon_index + 1; // Used for parsing later          this.ref = null;
371        }        }
372        else
   // Handle defaulting of protocol from context.  If no protocol and no  
   // context, then no URL.  
   if (protocol == null)  
     if (context == null)  
       throw new MalformedURLException(url);  
     else  
       protocol = context.getProtocol();  
   
   protocol = protocol.toLowerCase();  
   
   // Default in items as necessary  
   if (context != null)  
     if (context.getProtocol().toLowerCase().equals(protocol))  
373        {        {
374          host = context.getHost();          this.file = file.substring(0, hashAt);
375          port = context.getPort();          this.ref = file.substring(hashAt + 1);
         file = context.getFile();  
         if (file == null)  
           file = "";  
376        }        }
377        hashCode = hashCode();                      // Used for serialization.
378      }
379    
380    // Get the protocol handler and parse the rest of the URL string.    /**
381    if (ph != null)     * Initializes a URL from a complete string specification such as
382      {     * "http://www.urbanophile.com/arenn/".  First the protocol name is parsed
383        SecurityManager sm = System.getSecurityManager();     * out of the string.  Then a handler is located for that protocol and
384        if (sm != null)     * the parseURL() method of that protocol handler is used to parse the
385          sm.checkPermission(new NetPermission("specifyStreamHandler"));     * remaining fields.
386       *
387        this.ph = ph;     * @param spec The complete String representation of a URL
388      }     *
389    else     * @exception MalformedURLException If a protocol handler cannot be found
390      {     * or the URL cannot be parsed
391        this.ph = getProtocolHandler(protocol);     */
392      }    public URL(String spec) throws MalformedURLException
393      {
394    if (start == -1)      this((URL) null, spec, (URLStreamHandler) null);
395      start = 0;    }
396    
397    // We are supposed to stop parsing at the "#" char and treat everything    /*
398    // after that as an anchor.     * This method parses a String representation of a URL within the
399    end = url.indexOf("#");     * context of an existing URL.  Principally this means that any
400    if (end == -1)     * fields not present the URL are inheritied from the context URL.
401      end = url.length();     * This allows relative URL's to be easily constructed.  If the
402       * context argument is null, then a complete URL must be specified
403    // Ok, parseURL will not work here right now.  Instead, we just     * in the URL string.  If the protocol parsed out of the URL is
404    // do a hack by treating the spec URL as a file that should be     * different from the context URL's protocol, then then URL String
405    // appended to the context.  Only if the context is null do we try     * is also expected to be a complete URL.
406    // to parse.     *
407       * @param context The context on which to parse the specification
408        this.ph.parseURL(this, url, start, end);     * @param spec The string to parse an URL
409       *
410    hashCode = toString().hashCode();     * @exception MalformedURLException If a protocol handler cannot be found
411  }     * for the URL cannot be parsed
412       */
413  /*************************************************************************/    public URL(URL context, String spec) throws MalformedURLException
414      {
415  /**      this(context, spec, (URLStreamHandler) null);
416    * Initializes a URL from a complete string specification such as    }
   * "http://www.urbanophile.com/arenn/".  First the protocol name is parsed  
   * out of the string.  Then a handler is located for that protocol and  
   * the parseURL() method of that protocol handler is used to parse the  
   * remaining fields.  
   *  
   * @param url The complete String representation of a URL  
   *  
   * @exception MalformedURLException If a protocol handler cannot be found or the URL cannot be parsed  
   */  
 public  
 URL(String url) throws MalformedURLException  
 {  
   this(null, url);  
 }  
   
 /*************************************************************************/  
   
 /*  
  * Instance Methods  
  */  
   
 /**  
   * This protected method is used by protocol handlers to set the values  
   * of the fields in this URL.  This might be done in the parseURL method  
   * of that class.  
   *  
   * @param protocol The protocol name for this URL  
   * @param host The hostname or IP address for this URL  
   * @param port The port number of this URL  
   * @param file The "file" portion of this URL.  
   * @param ref The anchor portion of this URL.  
   */  
 protected synchronized void  
 set(String protocol, String host, int port, String file, String ref)  
 {  
   //*** Should we ignore null'd fields?  Assume not for now.  
   
   this.protocol = protocol;  
   this.host = host;  
   this.port = port;  
   this.file = file;  
   this.ref = ref;  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Returns the protocol name of this URL  
   *  
   * @return The protocol  
   */  
 public String  
 getProtocol()  
 {  
   return(protocol);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Returns the hostname or IP address for this protocol  
   *  
   * @return The hostname  
   */  
 public String  
 getHost()  
 {  
   return(host);  
 }  
   
 /*************************************************************************/  
   
 /**  
   * Returns the port number of this URL or -1 if the default port number is  
   * being used  
   *  
   * @return The port number  
   */  
 public int  
 getPort()  
 {  
   return(port);  
 }  
   
 /*************************************************************************/  
417    
418  /**    /**
419    * Returns the "file" portion of this URL     * Creates an URL from given arguments
420    *     * This method parses a String representation of a URL within the
421    * @return The file portion     * context of an existing URL.  Principally this means that any fields
422    */     * not present the URL are inheritied from the context URL.  This allows
423  public String     * relative URL's to be easily constructed.  If the context argument is
424  getFile()     * null, then a complete URL must be specified in the URL string.
425  {     * If the protocol parsed out of the URL is different
426    return(file);     * from the context URL's protocol, then then URL String is also
427  }     * expected to be a complete URL.
428       * <p>
429       * Additionally, this method allows the caller to specify a protocol handler
430       * to use instead of  the default.  If this handler is specified, the caller
431       * must have the "specifyStreamHandler" permission
432       * (see <code>NetPermission</code>) or a <code>SecurityException</code>
433       * will be thrown.
434       *
435       * @param context The context in which to parse the specification
436       * @param spec The string to parse as an URL
437       * @param handler The stream handler for the URL
438       *
439       * @exception MalformedURLException If a protocol handler cannot be found
440       * or the URL cannot be parsed
441       * @exception SecurityException If the <code>SecurityManager</code> exists
442       * and does not allow the caller to specify its own protocol handler.
443       *
444       * @since 1.2
445       */
446      public URL(URL context, String spec, URLStreamHandler handler)
447        throws MalformedURLException
448      {
449        /* A protocol is defined by the doc as the substring before a ':'
450         * as long as the ':' occurs before any '/'.
451         *
452         * If context is null, then spec must be an absolute URL.
453         *
454         * The relative URL need not specify all the components of a URL.
455         * If the protocol, host name, or port number is missing, the value
456         * is inherited from the context.  A bare file component is appended
457         * to the context's file.  The optional anchor is not inherited.
458         */
459    
460        // If this is an absolute URL, then ignore context completely.
461        // An absolute URL must have chars prior to "://" but cannot have a colon
462        // right after the "://".  The second colon is for an optional port value
463        // and implies that the host from the context is used if available.
464        int colon;
465        if ((colon = spec.indexOf("://", 1)) > 0 &&
466            ! spec.regionMatches(colon, "://:", 0, 4))
467          context = null;
468    
469        int slash;
470        if ((colon = spec.indexOf(':')) > 0 &&
471            (colon < (slash = spec.indexOf('/')) || slash < 0))
472          {
473            // Protocol specified in spec string.
474            protocol = spec.substring(0, colon).toLowerCase();
475            if (context != null && context.protocol.equals(protocol))
476              {
477                // The 1.2 doc specifically says these are copied to the new URL.
478                host = context.host;
479                port = context.port;
480                file = context.file;
481                authority = context.authority;
482              }
483          }
484        else if (context != null)
485          {
486            // Protocol NOT specified in spec string.
487            // Use context fields (except ref) as a foundation for relative URLs.
488            colon = -1;
489            protocol = context.protocol;
490            host = context.host;
491            port = context.port;
492            file = context.file;
493            authority = context.authority;
494          }
495        else        // Protocol NOT specified in spec. and no context available.
496          throw new
497              MalformedURLException("Absolute URL required with null context");
498    
499  /*************************************************************************/      if (handler != null)
500          {
501            SecurityManager s = System.getSecurityManager ();
502            if (s != null)
503              s.checkPermission (new NetPermission ("specifyStreamHandler"));
504    
505  /**          this.handler = handler;
506    * Returns the ref (sometimes called the "reference") portion of the        }
507    * URL      else
508    *        this.handler = getURLStreamHandler(protocol);
   * @return The ref  
   */  
 public String  
 getRef()  
 {  
   return(ref);  
 }  
509    
510  /*************************************************************************/      if (this.handler == null)
511          throw new MalformedURLException("Protocol handler not found: "
512                                          + protocol);
513    
514        // JDK 1.2 doc for parseURL specifically states that any '#' ref
515        // is to be excluded by passing the 'limit' as the indexOf the '#'
516        // if one exists, otherwise pass the end of the string.
517        int hashAt = spec.indexOf('#', colon + 1);
518        this.handler.parseURL(this, spec, colon + 1,
519                              hashAt < 0 ? spec.length() : hashAt);
520        if (hashAt >= 0)
521          ref = spec.substring(hashAt + 1);
522    
523  /**      hashCode = hashCode();                      // Used for serialization.
524    * Test another URL for equality with this one.  This will be true only if    }
   * the argument is non-null and all of the fields in the URL's match  
   * exactly (ie, protocol, host, port, file, and ref).  Overrides  
   * Object.equals().  
   *  
   * @param url The URL to compare with  
   *  
   * @return true if the URL is equal, false otherwise  
   */  
 public boolean  
 equals(Object url)  
 {  
   // Is it null?  
   if (url == null)  
     return(false);  
   
   // Is it a URL?  
   if (!(url instanceof URL))  
     return(false);  
   
   URL u = (URL)url;  
   
   // Check everything but the ref  
   if (!sameFile(u))  
     return(false);  
   
   // Do the ref's match  
   String s = u.getRef();  
   if (s != null)  
     if (!s.equals(getRef()))  
       return(false);  
   else if (getRef() != null)  
     return(false);  
525    
526    // Still here so everything must be ok    /**
527    return(true);     * Test another URL for equality with this one.  This will be true only if
528  }     * the argument is non-null and all of the fields in the URL's match
529       * exactly (ie, protocol, host, port, file, and ref).  Overrides
530       * Object.equals(), implemented by calling the equals method of the handler.
531       *
532       * @param url The URL to compare with
533       *
534       * @return true if the URL is equal, false otherwise
535       */
536      public boolean equals(Object obj)
537      {
538        if (obj == null || ! (obj instanceof URL))
539          return false;
540    
541  /*************************************************************************/      URL uObj = (URL) obj;
542    
543  /**      return handler.equals (this, uObj);
544    * Tests whether or not another URL refers to the same "file" as this one.    }
   * This will be true if and only if the passed object is not null, is a  
   * URL, and matches all fields but the ref (ie, protocol, host, port,  
   * and file);  
   *  
   * @param url The URL object to test with  
   *  
   * @return true if URL matches this URL's file, false otherwise  
   */  
 public boolean  
 sameFile(URL url)  
 {  
   if (url == null)  
     return(false);  
545    
546    // Do the protocol's match?    /**
547    String s = url.getProtocol();     * Returns the contents of this URL as an object by first opening a
548    if (s != null)     * connection, then calling the getContent() method against the connection
549      {     *
550        if (!s.equals(getProtocol()))     * @return A content object for this URL
551          return(false);     * @exception IOException If opening the connection or getting the
552      }     * content fails.
553    else if (getProtocol() != null)     *
554      return(false);     * @since 1.3
555       */
556      public final Object getContent() throws IOException
557      {
558        return openConnection().getContent();
559      }
560    
561    // Do the hostname's match?    /**
562    s = url.getHost();     * Gets the contents of this URL
563    if (s != null)     *
564      {     * @exception IOException If an error occurs
565        if (!s.equals(getHost()))     */
566          return(false);    public final Object getContent (Class[] classes) throws IOException
567      }    {
568    else if (getHost() != null)      // FIXME: implement this
569      return(false);      return getContent();
570      }
571    
572    // Do the port's match?    /**
573    if (url.getPort() != getPort())     * Returns the file portion of the URL.
574      return(false);     * Defined as <code>path[?query]</code>.
575       * Returns the empty string if there is no file portion.
576    // Do the file's match?     */
577    s = url.getFile();    public String getFile()
578    if (s != null)    {
579      {      return file == null ? "" : file;
580        if (!s.equals(getFile()))    }
         return(false);  
     }  
   else if (getFile() != null)  
     return(false);  
581    
582    // We're still here, so everything must be ok!    /**
583    return(true);     * Returns the path of the URL. This is the part of the file before any '?'
584  }     * character.
585       *
586       * @since 1.3
587       */
588      public String getPath()
589      {
590        int quest = file.indexOf('?');
591        return quest < 0 ? file : file.substring(0, quest);
592      }
593    
594  /*************************************************************************/    /**
595       * Returns the authority of the URL
596       *
597       * @since 1.3
598       */
599      public String getAuthority()
600      {
601        return authority;
602      }
603    
604  /*    /**
605    * This is the implementation of the Comparable interface for URL's.  It     * Returns the host of the URL
606    * will return a negative int, 0, or a positive int depending on whether     */
607    * a URL is less than, equal to, or greater than this URL respectively.    public String getHost()
608    * This is done by returning the compareTo result on this string    {
609    * representations of these URL's.      int at = (host == null) ? -1 : host.indexOf('@');
610    *      return at < 0 ? host : host.substring(at + 1, host.length());
611    * @param url The URL to compare against    }
   *  
   * @return An int indicating whether a URL is less than, equal to, or greater than this URL  
   *  
 public int  
 compareTo(Object url)  
 {  
   return(toExternalForm().compareTo(((URL)url).toExternalForm()));  
 }  
 */  
612    
613  /*************************************************************************/    /**
614       * Returns the port number of this URL or -1 if the default port number is
615       * being used.
616       *
617       * @return The port number
618       *
619       * @see #getDefaultPort()
620       */
621      public int getPort()
622      {
623        return port;
624      }
625    
626  /**    /**
627    * Returns a String representing this URL.  The String returned is     * Returns the default port of the URL. If the StreamHandler for the URL
628    * created by calling the protocol handler's toExternalForm() method.     * protocol does not define a default port it returns -1.
629    *     */
630    * @return A string for this URL    public int getDefaultPort()
631    */    {
632  public String      return handler.getDefaultPort();
633  toExternalForm()    }
 {  
   return(ph.toExternalForm(this));  
 }  
634    
635  /*************************************************************************/    /**
636       * Returns the protocol of the URL
637       */
638      public String getProtocol()
639      {
640        return protocol;
641      }
642    
643  /**    /**
644    * Returns a String representing this URL.  Identical to toExternalForm().     * Returns the ref (sometimes called the "# reference" or "anchor") portion
645    * The value returned is created by the protocol handler's     * of the URL.
646    * toExternalForm method.  Overrides Object.toString()     *
647    *     * @return The ref
648    * @return A string for this URL     */
649    */    public String getRef()
650  public String    {
651  toString()      return ref;
652  {    }
   return(toExternalForm());  
 }  
653    
654  /*************************************************************************/    /**
655       * Returns the user information of the URL. This is the part of the host
656       * name before the '@'.
657       *
658       * @return the user at a particular host or null when no user defined.
659       */
660      public String getUserInfo ()
661      {
662        int at = host.indexOf('@');
663        return at < 0 ? null : host.substring(0, at);
664      }
665    
666  /**    /**
667    * Returns a URLConnection for this object created by calling the     * Returns the query of the URL. This is the part of the file before the
668    * openConnection() method of the protocol handler     * '?'.
669    *     *
670    * @return A URLConnection for this URL     * @ return the query part of the file, or null when there is no query part.
671    *     */
672    * @exception IOException If an error occurs    public String getQuery ()
673    */    {
674  public synchronized URLConnection      int quest = file.indexOf('?');
675  openConnection() throws IOException      return quest < 0 ? null : file.substring(quest + 1, file.length());
676  {    }
   return(ph.openConnection(this));  
 }  
677    
678  /*************************************************************************/    /**
679       * Returns a hashcode computed by the URLStreamHandler of this URL
680       */
681      public int hashCode()
682      {
683        if (hashCode != 0)
684          return hashCode;          // Use cached value if available.
685        else
686          return handler.hashCode (this);
687      }
688    
689  /**    /**
690    * This method returns an InputStream for this URL by first opening the     * Returns a URLConnection object that represents a connection to the remote
691    * connection, then calling the getInputStream() method against the     * object referred to by the URL. The URLConnection is created by calling the
692    * connection.     * openConnection() method of the protocol handler
693    *     *
694    * @return An InputStream for this URL     * @return A URLConnection for this URL
695    *     * @exception IOException If an error occurs
696    * @exception IOException If an error occurs     */
697    */    public URLConnection openConnection() throws IOException
698  public final synchronized InputStream    {
699  openStream() throws IOException      return handler.openConnection(this);
700  {    }
   return(openConnection().getInputStream());  
 }  
701    
702  /*************************************************************************/    /**
703       * Opens a connection to this URL and returns an InputStream for reading
704       * from that connection
705       *
706       * @exception IOException If an error occurs
707       */
708      public final InputStream openStream() throws IOException
709      {
710        return openConnection().getInputStream();
711      }
712    
713  /**    /**
714    * Returns the contents of this URL as an object by first opening a     * Tests whether or not another URL refers to the same "file" as this one.
715    * connection, then calling the getContent() method against the connection     * This will be true if and only if the passed object is not null, is a
716    *     * URL, and matches all fields but the ref (ie, protocol, host, port,
717    * @return A content object for this URL     * and file);
718    *     *
719    * @exception IOException If an error occurs     * @param url The URL object to test with
720    */     *
721  public final synchronized Object     * @return true if URL matches this URL's file, false otherwise
722  getContent() throws IOException     */
723  {    public boolean sameFile(URL other)
724    return(openConnection().getContent());    {
725  }      return handler.sameFile(this, other);
726      }
727    
728  /*************************************************************************/    /**
729       * Sets the specified fields of the URL. This is not a public method so
730       * that only URLStreamHandlers can modify URL fields. This might be called
731       * by the <code>parseURL()</code> method in that class. URLs are otherwise
732       * constant.
733       *
734       * @param protocol The protocol name for this URL
735       * @param host The hostname or IP address for this URL
736       * @param port The port number of this URL
737       * @param file The "file" portion of this URL.
738       * @param ref The anchor portion of this URL.
739       */
740      protected void set(String protocol, String host, int port, String file,
741                         String ref)
742      {
743        // TBD: Theoretically, a poorly written StreamHandler could pass an
744        // invalid protocol.  It will cause the handler to be set to null
745        // thus overriding a valid handler.  Callers of this method should
746        // be aware of this.
747        this.handler = getURLStreamHandler(protocol);
748        this.protocol = protocol.toLowerCase();
749        this.authority = null;
750        this.port = port;
751        this.host = host;
752        this.file = file;
753        this.ref = ref;
754        hashCode = hashCode();                      // Used for serialization.
755      }
756    
757  /**    /**
758    * This method returns a hash value for this object.     * Sets the specified fields of the URL. This is not a public method so
759    *     * that only URLStreamHandlers can modify URL fields. URLs are otherwise
760    * @return a hash value for this object.     * constant.
761    */     *
762  public int     * @since 1.3
763  hashCode()     */
764  {    protected void set(String protocol, String host, int port,
765    return(hashCode);                       String authority, String userInfo,
766  }                       String path, String query, String ref)
767      {
768        // TBD: Theoretically, a poorly written StreamHandler could pass an
769        // invalid protocol.  It will cause the handler to be set to null
770        // thus overriding a valid handler.  Callers of this method should
771        // be aware of this.
772        this.handler = getURLStreamHandler(protocol);
773        this.protocol = protocol.toLowerCase();
774        if (userInfo == null)
775          this.host = host;
776        else
777          this.host = userInfo + "@" + host;
778        this.port = port;
779        if (query == null)
780          this.file = path;
781        else
782          this.file = path + "?" + query;
783        this.ref = ref;
784        hashCode = hashCode();                      // Used for serialization.
785      }
786    
787  //According to Java API Documentation "Serialized form"    /**
788  private synchronized void writeObject(ObjectOutputStream stream)     * Sets the URLStreamHandlerFactory for this class.  This factory is
789    throws IOException     * responsible for returning the appropriate protocol handler for
790  {     * a given URL.
791    stream.defaultWriteObject();    // write the fields     *
792  }     * @param fac The URLStreamHandlerFactory class to use
793       *
794       * @exception Error If the factory is alread set.
795       * @exception SecurityException If a security manager exists and its
796       * checkSetFactory method doesn't allow the operation
797       */
798      public static synchronized void
799            setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
800      {
801        if (factory != null)
802          throw new Error("URLStreamHandlerFactory already set");
803    
804        // Throw an exception if an extant security mgr precludes
805        // setting the factory.
806        SecurityManager s = System.getSecurityManager();
807        if (s != null)
808          s.checkSetFactory();
809        factory = fac;
810      }
811    
812  private synchronized void readObject(ObjectInputStream stream)    /**
813    throws IOException, ClassNotFoundException     * Returns a String representing this URL.  The String returned is
814  {     * created by calling the protocol handler's toExternalForm() method.
815    stream.defaultReadObject();     // read the fields     *
816    ph = getProtocolHandler(protocol);     * @return A string for this URL
817    if (ph == null)     */
818      throw new IOException("Can't handle protocol: " + protocol);    public String toExternalForm()
819  }    {
820        // Identical to toString().
821        return handler.toExternalForm(this);
822      }
823    
824  /**    /**
825   * Return the path portion of this URL     * Returns a String representing this URL.  Identical to toExternalForm().
826   *     * The value returned is created by the protocol handler's
827   * @since 1.3     * toExternalForm method.  Overrides Object.toString()
828   */     *
829  public String getPath()     * @return A string for this URL
830  {     */
831    return file;    public String toString()
832      {
833        // Identical to toExternalForm().
834        return handler.toExternalForm(this);
835      }
836    
837      private void readObject(ObjectInputStream ois)
838        throws IOException, ClassNotFoundException
839      {
840        ois.defaultReadObject();
841        this.handler = getURLStreamHandler(protocol);
842        if (this.handler == null)
843          throw new IOException("Handler for protocol " + protocol + " not found");
844      }
845    
846      private void writeObject(ObjectOutputStream oos) throws IOException
847      {
848        oos.defaultWriteObject();
849      }
850  }  }
   
   
 } // class URL  
   

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26